Repository navigation
Releases: ExeQue/laravel-zipstream
Release list
1.1.2
Fixes #7: toResponse() no longer throws ini_set(): Cannot change zlib.output_compression - headers already sent after every download under PHP-FPM and other SAPIs that send output.
zlib.output_compression is turned off only when it is on, and it is left off afterwards. PHP refuses to change it once output has gone out, and it resets the setting itself when the request ends.
1.1.1
Documentation only: no code changed between 1.1.0 and this.
UPGRADE.md ships with the package, and the section covering 1.0 to 1.1 was written after 1.1.0 was tagged - so an application installing 1.1.0 got a guide that stopped at 1.0. This tag carries it.
It matters for the laravel-zipstream-upgrade Boost skill, which reads the guide from vendor/exeque/laravel-zipstream/UPGRADE.md rather than from the web.
1.1.0
An event handler takes the event first, and after it may ask for the archive it belongs to, or for anything the
container can build.
$zip->on(fn (ProcessError $e, ArchiveBuilder $zip, LoggerInterface $log) => $zip->abort());
$zip->on(fn (StreamedBytes $e, Container $app) => $app->make(ProgressStore::class)->put($e->context));That saves closing over the builder to reach abort(), and saves a handler resolving its own dependencies.
Parameters are matched by type; anything the container cannot build and that has no default is refused when the
handler is registered rather than when it fires.
Existing handlers are unaffected. PHP passes extra arguments to a closure or a method without complaint.
Also in this release
- The archive cannot be restructured from a handler. Entries are taken when a run starts, so one added while
it writes would never reach the archive being produced.add()throwsArchiveFrozenExceptionfor the length
of the run, and the builder reopens afterwards - including after an abort. - The event queue comes from the container, so an application can bind its own. A queue built by hand has no
container, and a handler asking it for something throws with the name of what was missing.
Upgrading
Nothing to do for normal use. Two constructors changed for anyone building the pieces by hand rather than
resolving them: Builder takes the container as its third argument, and Pending::process() requires the
EventQueue it used to default.
1.0.0
Everything streams. An archive of any size is built while it is written, at constant memory, whether it goes to
a browser, a Laravel disk or a local path.
Upgrading from 0.x? Start with the upgrade guide. Every breaking change is there with before and after.
The fix this release started as
saveToDisk() built the whole archive into php://temp before writing a byte, so peak local disk - or memory,
when the temp directory was not writable - equalled the archive size. A 129 MB archive exhausted a default
128 MB memory_limit.
ZipStream pushes while Flysystem and the AWS SDK pull. The archive is now produced inside a Fiber that the
reader drives, so only one chunk is ever held. A failed write leaves nothing behind: the S3 multipart upload is
aborted, the key removed only if this call created it, and the original exception rethrown.
What else is new
- Events are objects. A handler declares what it listens for by type-hinting its first parameter, and every
event carries a frozenContextwith the archive id, the entry being streamed and how far along it is. - Progress reports itself, throttled by bytes or by an interval, and renders as
"10 of 125 files"or
"5.00 KB of 64.00 MB"in thirty European languages. abort()stops an archive from a handler;abort(discard: true)throws it away, upload and all.fromDiskDirectory()andfromLocalDirectory()add a whole prefix from one listing, sizes included.Zip::fake()records what an archive would have contained, so composition is testable without storage.- The response owns PHP's output layer - zlib, buffers, encoding, time limit - so a large download streams
rather than stalls. ArchiveBuilderdeclares the public surface, with tests that fail on anything public it does not cover.
Breaking changes
output(bool)split intotoString()andtoStream(); the stream is read-once and not seekableEventTypegone;$event->idis$event->context->id, and the event interfaces moved toEvents\ContractszeroHeader(?bool)replaced bywithZeroHeader(),withoutZeroHeader()andinheritZeroHeader()Content-Typeisapplication/zip, and a plain filename is no longer quotedsaveToDisk()takes$options, andDiskFile::make()takes aFilesystemAdapter- A failed write cleans up after itself, which includes deleting a path this call created
- Three new config keys:
progress_every,size_precision,manage_output
Documentation
exeque.github.io/laravel-zipstream - including driver pages for
S3 as both source and destination.
Throw on failed stream reads, route process errors through events
Full Changelog: 0.1.2...0.1.3
Add forward for `withoutVerification`
Full Changelog: 0.1.1...0.1.2
Skip verification
Added events system
Move Laravel Boost skill into the correct directory
0.0.5 Whoops!
Updated agent skill
0.0.4 docs: add examples for custom contracts and macros in Laravel ZipStre…