Search code examples
phpsymfonysymfony-3.4

Create and Download Zip File (maennchen/ZipStream-PHP)


In my project we used maennchen/ZipStream-PHP bundle. Now I'm trying to create and download zip file, but when I open the zip file I have an error "empty archive".

return new StreamedResponse(function() use ($filenames, $logger) {
        $filename = 'example.zip';

        $opt = new ArchiveOptions();
        $opt->setContentDisposition("attachment;filename=\"$filename\"");
        $opt->setContentType('application/octet-stream');
        $opt->setEnableZip64(false);
        $opt->setFlushOutput(true);
        $opt->setSendHttpHeaders(true);

        $zip = new ZipStream($filename, $opt);

        foreach ($filenames as $f) {
            if (true === file_exists($f)) {
                try {
                    $zip->addFileFromPath(basename($f), $f);
                } catch (\Exception $exception) {
                    $logger->error($exception->getMessage());
                }
            } else {
                $logger->error(sprintf('File %s does not exist.', $f));
            }
        }

        $zip->finish();
    });

If I dump $zip then the file argument is empty. I think the addFile method does not work.

Can you help me?

Thanks in advance.


Solution

  • Symfony's StreamedResponse is sending the headers already, so you should not override them inside the "stream"

    Try this;

    return new StreamedResponse(function() use ($filenames, $logger) {
            $opt = new \ZipStream\Option\Archive();
            $opt->setZeroHeader(true);
            $opt->setEnableZip64(false);
    
            $zip = new ZipStream(null, $opt);
    
            foreach ($filenames as $f) {
                if (true === file_exists($f)) {
                    try {
                        $zip->addFileFromPath(basename($f), $f);
                    } catch (\Exception $exception) {
                        $logger->error($exception->getMessage());
                    }
                } else {
                    $logger->error(sprintf('File %s does not exist.', $f));
                }
            }
    
            $zip->finish();
        },
        200,
        [
            'Content-Disposition' => 'attachment;filename="example.zip"',
            'Content-Type' => 'application/octet-stream',
        ]);