nemo64/zip-stream

Quickly stream multiple files without creating an archive first.

v1.0.0 2019-01-28 15:43 UTC

This package is auto-updated.

Last update: 2024-10-29 03:33:05 UTC


README

Build Status Latest Stable Version Total Downloads Monthly Downloads License

ZIP Stream

This library allows you to create an PSR-7 stream which contains multiple files in a zip format. This is done without actually creating a zip file at any time and is therefore very light on resources. In fact, there should be very little difference compared to just sending the file though php.

Here are some special characteristics:

  • no files are created so no cleanup is nessesary
  • the length of the file is known before sending it making a Content-Length header possible (which let's the user know how long the download takes)
  • it is possible to resume a download if your psr7-emitter/framework supports it.
  • you don't have to output the stream to the browser, for example you can stream it using guzzle in a post request.
  • there are no platform dependencies. You don't need ext-zip or the zip command on your machine.

But there are also some limitations:

  • The created zip file has no compression at all. This is necessary for the quick size calculation. If you need that use maennchen/zipstream-php
  • There is no Zip64 implementation yet so you are limited to 4GB files. There might be additional limitations in 32 bit php which I haven't investigated yet.

Example

You'll need a way to send PSR-7 Response objects to the client. Some Frameworks start to support this but in the mean time i'll recommend you use an external library like arrowspark/http-emitter to do just that.

use function GuzzleHttp\Psr7\stream_for;
use function GuzzleHttp\Psr7\try_fopen;
use Narrowspark\HttpEmitter\SapiStreamEmitter;
use Nemo64\ZipStream\ZipResponse;
use Nemo64\ZipStream\ZipStream;

$zip = new ZipStream();
$zip->add('file1.jpg', stream_for(try_fopen('file1.jpg', 'r')));

// be sure that before you send this response that there is no output buffering engaged.
while (@ob_end_clean()) {}

$response = ZipResponse::create($zip, 'my_archive.zip');
$emitter = new SapiStreamEmitter();
$emitter->emit($response);