Téléchargement d'un fichier généré dynamiquement depuis un contrôleur Symfony
Publié le 10/01/2021 • Actualisé le 10/01/2021
Dans un snippet précédent, nous avons vu comment forcer le téléchargement d'un fichier existant à partir d'un contrôleur Symfony. Généralement on veut fournir du contenu dynamique comme lors d'un export CSV. Dans celui-ci ; nous allons utiliser un fichier temporaire pour ne pas avoir en générer un dans le répertoire public ; ce serait une faille de sécurité.
<?php
declare(strict_types=1);
namespace App\Controller\Snippet;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpKernel\KernelInterface;
/**
* J'utilise un trait PHP afin d'isoler chaque snippet dans un fichier.
* Ce code doit être apellé d'un contrôleur Symfony étendant AbstractController (depuis Symfony 4.2)
* ou Symfony\Bundle\FrameworkBundle\Controller\Controller (Symfony <= 4.1).
* Les services sont injectés dans le constructeur du contrôleur principal.
*
* @property KernelInterface $kernel
*/
trait Snippet129Trait
{
public function snippet129(): BinaryFileResponse
{
$tmpFileName = (new Filesystem())->tempnam(sys_get_temp_dir(), 'sb_');
$tmpFile = fopen($tmpFileName, 'wb+');
if (!\is_resource($tmpFile)) {
throw new \RuntimeException('Unable to create a temporary file.');
}
$data = [
['name', 'firstname', 'age'],
['COil', 'Doo', random_int(30, 42)],
['Fab', 'Pot', random_int(30, 42)],
['Glas', 'Dun', random_int(30, 42)],
];
foreach ($data as $line) {
fputcsv($tmpFile, $line, ';');
}
$response = $this->file($tmpFileName, 'dynamic-csv-file.csv');
$response->headers->set('Content-type', 'application/csv');
fclose($tmpFile);
return $response; // That's it! 😁
}
}
Exécuter le snippet Plus sur Stackoverflow Snippet aléatoire