maennchen/ZipStream-PHP: Streaming ZIP Downloads in PHP
:floppy_disk: PHP ZIP Streaming Library
At a glance
- What is it?
- ZipStream-PHP is a PHP library for generating ZIP archives as output streams, including browser downloads, PSR-7 streams, and S3-backed workflows. It is a focused option when building an archive in memory or on a temporary file is unnecessary, but its current release line requires careful attention to PHP and 64-bit platform requirements.
- Who is it for?
- Adopt ZipStream-PHP when a PHP application must assemble a ZIP response as files are added and send the result to a client or stream destination. Do not choose it for an application that cannot meet the documented PHP and platform requirements, or when a complete local temporary archive is an acceptable design.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly PHP, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Star history
- maennchen/ZipStream-PHP1,910 ★ · +2
| Repository | 2026-10-16 | 2026-10-23 |
|---|---|---|
| maennchen/ZipStream-PHP | 1.9k | 1.9k |
2 Stars in the last 7 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
What ZipStream-PHP is designed to solve
ZipStream-PHP addresses a specific PHP web application problem: creating a ZIP file for download without first writing the complete archive to disk. The README describes it as a streaming ZIP download library and says the generated output can be sent directly to the user. That design matters when an application combines several generated files or selected source files into one download and wants the response to begin before the entire archive has been assembled.
The intended users are PHP developers building HTTP download endpoints, report exports, media bundles, backup streams, or other features that produce a ZIP archive on demand. The library also supports S3 buckets and PSR-7 streams, so its scope extends beyond a direct browser response. The callback example shows that ZIP bytes can be intercepted while they are generated and sent to more than one destination.
This is not a general-purpose filesystem archiver presented as a command-line replacement. The documented interface centers on PHP objects, named arguments, output streams, and ZIP entry methods. The project documentation also directs developers to its external documentation for detailed usage, so the README is an introduction rather than a complete API reference. The library name and package identifier are both `maennchen/ZipStream-PHP`, while the Composer package is `maennchen/zipstream-php`.
The streaming architecture behind ZipStream-PHP
The central object is `ZipStream\ZipStream`. A caller creates it with an output name, selects an output destination, and then adds entries through methods such as `addFile` and `addFileFromPath`. Calling `finish()` completes the archive stream. The README's basic example uses `sendHttpHeaders: true`, allowing the library to emit the HTTP headers associated with the download. The constructor also supports an `outputStream`, which changes the destination from the default response path to another stream or wrapper.
The architecture is therefore incremental. Entry data is handed to ZipStream-PHP, the library produces ZIP output as processing proceeds, and the configured stream receives that output. The README says the library can work with S3 buckets or any PSR-7 Stream, which indicates that the archive writer is separated from the response destination. A caller can therefore use HTTP output, an application-managed stream, or an object-storage integration when the surrounding code supplies the appropriate stream.
The callback example makes the data flow explicit. `CallbackStreamWrapper::open()` accepts a closure that receives string data as the ZIP stream is generated. The closure writes each chunk to `output.zip`, echoes it to the browser, and writes it to `backup.zip`. This is useful for fan-out, but it also means the application must manage resource lifetime and error handling for the opened files. The library receives the generated bytes, but it does not make the caller's file writes transactional.
Installing ZipStream-PHP with Composer
The README gives Composer as the installation route. Run this from the PHP project that should depend on ZipStream-PHP. The command adds the package to the project's dependencies and updates `composer.json` and `composer.lock` as Composer normally does.
composer require maennchen/zipstream-phpAfter installation, use the project's autoloader in the same entry-point script that will generate the archive. The upgrade notes state that version 3.1.2 requires PHP 8.2. The notes for version 3.0.0 also state that only 64-bit architecture is supported. Those requirements should be checked before installation, especially in a build image or deployment platform where the PHP binary and architecture may differ from a local workstation.
The default branch is explicitly not stable according to the README. It directs users to the releases page for a stable version. Composer installation should therefore be performed in an environment with a deliberate version policy, rather than by assuming that the current `main` branch represents the production API. The README identifies version 3 as the line receiving new features, bug fixes, and security work, while version 2 is limited to security support.
Creating a first browser ZIP response
The following is the README's first usage example. It creates `example.zip` as the output name, enables HTTP headers, adds one in-memory text entry, adds one file from a local path, and finishes the stream. Replace the image path with a file that exists in the application environment.
require 'vendor/autoload.php';
$zip = new ZipStream\ZipStream(
outputName: 'example.zip',
sendHttpHeaders: true,
);
$zip->addFile(
fileName: 'hello.txt',
data: 'This is the contents of hello.txt',
);
$zip->addFileFromPath(
fileName: 'some_image.jpg',
path: 'path/to/image.jpg',
);
$zip->finish();The expected client-facing artifact is a ZIP download containing `hello.txt` and `some_image.jpg`. The example does not specify compression settings, because the default behavior is used. It also does not show exception handling. A production endpoint should account for failures while reading a source file or writing the response, but the README does not document a particular retry or rollback procedure.
For an application that writes the response to a controlled stream, the callback pattern changes only the output destination. The following block demonstrates the documented fan-out pattern. Open both files before constructing the stream and close them after `finish()` returns.
use ZipStream\ZipStream;
use ZipStream\Stream\CallbackStreamWrapper;
$outputFile = fopen('output.zip', 'wb');
$backupFile = fopen('backup.zip', 'wb');
$zip = new ZipStream(
outputStream: CallbackStreamWrapper::open(function (string $data) use ($outputFile, $backupFile) {
fwrite($outputFile, $data);
echo $data;
fwrite($backupFile, $data);
}),
sendHttpHeaders: false,
);
$zip->addFile('hello.txt', 'Hello World!');
$zip->finish();
fclose($outputFile);
fclose($backupFile);Version 3 API boundaries and upgrade choices
Version 3 is not a drop-in continuation of the older API. The upgrade notes say that most classes are marked `@internal` and should not be used from outside the library. The documented external classes and enums are `ZipStream\CompressionMethod`, the `ZipStream\Exception*` types, and `ZipStream\ZipStream`. Code that previously extended internal resources may therefore require redesign before moving to version 3.
Several configuration names changed. `ZipStream\Option\Method` became `ZipStream\CompressionMethod`. `ZipStream\Option\Archive` and `ZipStream\Option\File` were replaced by named constructor and `addFile*` arguments. The archive option `deflateLevel` became `defaultDeflateLevel`, and `zeroHeader` became `defaultEnableZeroHeader`, with the latter defaulting to `true`. The file options `method`, `time`, and `size` became `compressionMethod`, `lastModificationDateTime`, and `maxSize`.
The removed `largeFileSize` and `largeFileMethod` options are a practical limitation. Applications that choose compression based on file size must implement that policy themselves. The removed `statFiles` option also reflects a documented change: the library no longer checks file sizes in that way. These changes favor a smaller public surface, but they increase migration work for applications built around the former option classes or internal extension points.
When streaming ZIP output is the wrong choice
ZipStream-PHP is a poor fit when the application cannot guarantee a writable output destination for the entire response. A browser download, S3 stream, PSR-7 stream, or callback may be appropriate, but the caller still has to manage the destination and any secondary files created by its own code. The callback example writes to two files and echoes to the browser, so it creates a second consistency problem if one destination succeeds and another fails.
It is also unsuitable for environments that do not meet the stated platform constraints. The upgrade documentation requires PHP 8.2 for version 3.1.2 and says version 3 supports only 64-bit architecture. A 32-bit PHP deployment cannot be treated as compatible simply because the package installs. Likewise, an application that needs undocumented internals should not assume that those classes remain available in future version 3 releases.
Compared with building a ZIP file first and serving it afterward, ZipStream-PHP changes the operational model. A temporary-file approach can simplify inspection, resumption, and error handling because the archive exists as a complete local artifact. Streaming avoids that intermediate file, but it places more responsibility on the output path and the surrounding application. The project documentation does not claim that streaming archives support browser resume or provide automatic cleanup of partially written destinations.
ZipStream-PHP maintenance, licensing, and adoption fit
The repository is not archived, and its last push was on 2026-10-14. The listed releases include 3.2.2 on 2026-04-11, 3.2.1 on 2025-12-10, and 3.2.0 on 2025-07-17. The README's version table says version 3 receives new features, bug fixes, and security work, while version 2 receives security work. It also says support follows PHP core support. This is a current release line with a stated support policy, not a version 2 or version 1 target.
The project uses the MIT license. The README points readers to the `LICENSE` file for licensing and warranty information. That supports use in MIT-compatible projects, but the license file and the application's own obligations should be reviewed directly. The README does not provide a legal interpretation or claim that the library removes all attribution requirements.
For adoption, the deciding question is whether the application can work with PHP 8.2, a 64-bit runtime, the version 3 named-argument API, and a carefully selected stream destination. A team that needs a local, inspectable archive or depends on old internal classes should first inspect the release documentation and migration notes. The correct next step is to pin a stable release and validate the exact output path, because the library's core value is not ZIP creation by itself but controlled ZIP generation during an active stream.
Editorial conclusion
Adopt ZipStream-PHP when a PHP application must assemble a ZIP response as files are added and send the result to a client or stream destination. Do not choose it for an application that cannot meet the documented PHP and platform requirements, or when a complete local temporary archive is an acceptable design. Before adoption, verify the exact release, PHP version, architecture, output destination, and whether the application relies on any internal classes that version 3 marks as unavailable for external use.
Frequently asked questions
How do I install ZipStream-PHP in a PHP project?
The README documents Composer installation with the `maennchen/zipstream-php` package. The upgrade notes require PHP 8.2 for version 3.1.2 and state that version 3 supports only 64-bit architecture.
Can ZipStream-PHP send a ZIP to S3 or a PSR-7 stream?
Yes, according to the README. It says the library can work with S3 buckets or any PSR-7 Stream, and its constructor accepts an `outputStream` for selecting a destination.
How do I stream ZIP data to multiple destinations?
The README shows `CallbackStreamWrapper::open()` with a callback that receives generated ZIP data. The example writes that data to two files and echoes it to the browser, then closes the files after `finish()`.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/maennchen-zipstream-php)Star history chart for your README
[](https://hysenlabs.com/projects/maennchen-zipstream-php)Was this useful?