maennchen/zipstream-php
Stream ZIP archives on the fly in PHP without writing to disk. Fast ZIP downloads with optional HTTP headers, supports adding files from strings/paths, works with S3 and PSR-7 streams, and can output to custom callbacks.
Response::stream(), Symfony StreamedResponse) and integrates seamlessly with:
return $zip->finish()).addFileFromPath() or PSR-7 streams.Symfony\Component\HttpFoundation\StreamedResponse).php artisan export:zip).Model::saved()).3.2.2 (latest stable) and audit usage of @internal classes.Symfony HttpFoundation (e.g., StreamedResponse compatibility).ini_get('memory_limit')).CallbackStreamWrapper for custom sinks (e.g., S3) to avoid buffering issues.ZipArchive (disk-based) for files >1GB?microtime(true) in a Laravel test suite.ZipStream in a try-catch and return a fallback (e.g., partial ZIP or error page).../malicious.zip).Str::of($filename)->startsWith('safe/').ZipStream leverage Laravel’s Filesystem or Storage facades for file sources?addFileFromPath() to accept Storage::disk()->path().return response()->download($path) with ZipStream for dynamic content.ZipStream in queued jobs (e.g., HandleExportJob) to avoid blocking requests.Route::get('/export', function() { ... }) without temporary files.CallbackStreamWrapper to pipe ZIPs directly to AWS S3 (example in release 3.2.2).EmbeddedFile or StreamedFile./reports/export) with ZipStream.// Before (disk-based)
return response()->download(storage_path('reports.zip'));
// After (streaming)
$zip = new ZipStream\ZipStream('reports.zip', sendHttpHeaders: true);
$zip->addFile('data.csv', $csvData);
return $zip->finish();
ExportZipJob) with ZipStream in handle().public function handle() {
$zip = new ZipStream\ZipStream('export.zip');
$zip->addFileFromPath('file.txt', storage_path('temp/file.txt'));
return $zip->finish(); // Stream to client via queue worker
}
ZipArchive usages and replace with ZipStream where disk I/O is a bottleneck.ZipStream’s PHP 8.1+ requirement.ZipStream fork.GuzzleHttp\Psr7\Stream) and PSR-15 middleware.Symfony\Component\HttpFoundation\StreamedResponse for Laravel HTTP responses.composer.json:
"require": {
"maennchen/zipstream-php": "^3.2"
}
composer update.defaultDeflateLevel in ZipStream constructor for consistent compression.$zip = new ZipStream\ZipStream(
outputName: 'export.zip',
sendHttpHeaders: true,
defaultDeflateLevel: 6 // Balance speed/compression
);
ZipStream logic (e.g., file addition, compression).Storage::delete()).^3.2 in composer.json to auto-update patches.ZipStream\Exception\StreamException) via Laravel’s App\Exceptions\Handler.StreamedResponse with timeout parameter.memory_limit for large ZIPs or chunk data.ZipStream’s debug mode (if available) or log raw stream data.ZipStream instances in shared-nothing architectures.php -d memory_limit=512M.deflateLevel for large files (e.g., 3 instead of 9).supervisor) to free up web servers.| Failure Scenario | Impact | Mitigation |
|---|---|---|
| Client disconnects mid-stream | Partial ZIP or timeout | Implement retry logic or fallback to disk-based ZIP. |
| Memory exhaustion | Worker crash | Increase memory_limit or chunk data into smaller ZIPs. |
| Cor |
How can I help you explore Laravel packages today?