Raccourcis : Contenu - rubriques - sous rubriques
EN FR

Pour renvoyer un fichier binaire (un exécutable, une image, une vidéo, une archive ou autre), il faut utiliser jResponseBinary dont l'alias est "binary"


$rep = $this->getResponse('binary');

En premier lieu, il vous faut indiquer dans la propriété $outputFileName le nom de fichier sous lequel apparaîtra le contenu à l'utilisateur.


 $rep->outputFileName = 'monfichier.gif';

Vous pouvez aussi définir le type mime du contenu :


 $rep->mimeType = 'image/gif';

Et vous devez aussi spécifier si le fichier doit être proposé à l'utilisateur pour l'enregistrement ou non. Pour des fichiers couramment pris en charge par les navigateurs (les images par exemple), on mettra false :


 $rep->doDownload = false;

Ensuite pour le contenu, vous pouvez indiquer soit un fichier existant, soit du contenu que vous générez vous-même.

Pour renvoyer un fichier existant :


 $rep->fileName = jApp::varPath('fichier_a_renvoyer.gif');

Et sinon, si vous générez vous-même, mettez le contenu dans une chaîne et mettez le dans content :


 $rep->content = '...';

Cependant, cela prendra autant de mémoire que la taille du contenu, ce qui peut être problématique si le contenu est volumineux (plusieurs megaoctets). PHP pourrait interrompre brusquement le script si il n'y a plus assez de mémoire.

Pour les contenus volumineux, il est préférable d'envoyer directement le contenu au fur et à mesure qu'on le génère ou qu'on le lit à partir d'une source de données.

Pour cela, on peut donnée à jResponseBinary, soit une fonction de callback qui sera appelée au moment où Jelix demandera d'envoyer le contenu, soit un iterateur/générateur. Il faut utiliser respectivement les méthodes setContentCallback() et setContentGenerator().

Exemple, en donnant en réponse le contenu de la réponse à une requête HTTP, effectuée avec la bibliothèque GuzzleHttp :



// on prépare et envoie la requête à un service tiers
$client = new GuzzleHttp\Client();
$request = new GuzzleHttp\Psr7\Request('GET', 'https://foo.example/content', $headers);
$response = $client->send($request, ['stream' => true]);

// on récupère la réponse sous forme de flux, qui n'est pas encore consommé
$stream = $response->getBody();

$rep = $this->getResponse('binary');

// on donne une fonction de callback, qui lira le flux et l'enverra sur la sortie de PHP (`php://output`),
// grâce à cet utilitaire copyToStream
$rep->setContentCallback(function () use ($response) {
    $output = Psr7\Utils::streamFor(fopen('php://output', 'w+'));
    Psr7\Utils::copyToStream( $response->getBody(), $output);
});
// ..
return $rep;

Autre exemple avec un générateur

`

class Business {

    // this function is a generator, because of the use of yield
    public function getAllData()
    {
        $db = jDb::getConnection();
        $resultSet = $db->query("SELECT field1, field2, field3 FROM hugeTable")
        foreach($resultSet as $record) {
            yield $record->field1.';'.$record->field2.';'.$record->field3."\n";
        }
    }

}

// Into the controller:

$obj = new Business();

$rep = $this->getResponse('binary'); $rep->setContentGenerator($obj->getAllData()); // .. return $rep; `