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']);
// this generates the PDF contents but does not output them anywhere

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

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/')
           ->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, '')