Creating ZIP files and streaming the response with Silex

Creating a zip file is easy and Rob Allen has you covered on that front to get you started. I needed to do this to create a zip file of PDF files generated by Dompdf. It turns out, you can add files to a ZipArchive object without actually creating the file if you can get the contents as a string. This boils down to:

// $html is what you're going to render.
$dompdf = new DOMPDF(['defaultPaperOrientation' => 'landscape']);
$dompdf->loadHtml($html);
// this generates the PDF contents but does not output them anywhere
$dompdf->render(); 

// now we create a zip file and add the PDF
$zip = new ZipArchive();
$zip->open('/tmp/archive.zip', ZipArchive::CREATE);
// 'report.pdf' is the filename inside the zip archive
$zip->addFromString('report.pdf', $dompdf->output());
$zip->close();

The above adds one file, clearly if you want to create multiple PDFs, you would do that in a loop and call addFromString for each one. Then, if you want to stream the response to the browser with Silex (which uses Symfony components) you do:

use use Symfony\Component\HttpFoundation\ResponseHeaderBag; 

// ...

// at the end of a controller...
return $app->sendFile('/tmp/example.zip')
           ->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, 'your-report.zip')
           ->deleteFileAfterSend(true);