Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create a zip file using PHP class ZipArchive without writing the file to disk?

Tags:

php

ziparchive

I would like to create a zip file in memory using a ZipArchive (or a native PHP class) and read the content of the file back to the client. Is this possible? If so, how?

The files that I want to zip in this application are a maximum of 15 MB total. I think we should be in good shape memory-wise.

like image 496
CLJ Avatar asked Nov 12 '10 13:11

CLJ


3 Answers

Try ZipStream (link to GitHub repo, also supports install via Composer).

From original author's website (now dead):

ZipStream is a library for dynamically streaming dynamic zip files from PHP without writing to the disk at all on the server.

like image 193
Frosty Z Avatar answered Nov 08 '22 04:11

Frosty Z


Take a look at the following library, it allows creating zip files and returning them as a stream: PHPClasses.org.

like image 31
Cpt. eMco Avatar answered Nov 08 '22 02:11

Cpt. eMco


Thanks to Frosty Z for the great library ZipStream-PHP. We have a use case to upload some large zip files in quantity and size to S3. The official documentation does not mention how to upload to S3.

So we've had an idea to stream the zip created by ZipStream output directly to S3 without creating the zip file on the server.

Here is a working sample code that we came up with:

<?php
# Autoload the dependencies
require 'vendor/autoload.php';

use Aws\S3\S3Client;
use ZipStream\Option\Archive as ArchiveOptions;

//s3client service
$s3Client = new S3Client([
    'region' => 'ap-southeast-2',
    'version' => 'latest',
    'credentials' => [
        'key' => '<AWS_KEY>',
        'secret' => '<AWS_SECRET_KEY>',
    ]
]);
$s3Client->registerStreamWrapper(); //required

$opt = new ArchiveOptions();
$opt->setContentType('application/octet-stream');
$opt->setEnableZip64(false); //optional - for MacOs to open archives

$bucket = 'your_bucket_path';
$zipName = 'target.zip';

$zip = new ZipStream\ZipStream($zipName, $opt);

$path = "s3://{$bucket}/{$zipName}";
$s3Stream = fopen($path, 'w');

$zip->opt->setOutputStream($s3Stream); // set ZipStream's output stream to the open S3 stream

$filePath1 = './local_files/document1.zip';
$filePath2 = './local_files/document2.zip';
$filePath3 = './local_files/document3.zip';

$zip->addFileFromPath(basename($filePath1), $filePath1);
$zip->addFileFromPath(basename($filePath2), $filePath2);
$zip->addFileFromPath(basename($filePath3), $filePath3);

$zip->finish(); // sends the stream to S3
?>
like image 4
Terry Truong Avatar answered Nov 08 '22 04:11

Terry Truong