简体   繁体   中英

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

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.

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.

看看下面的库,它允许创建 zip 文件并将它们作为流返回: PHPClasses.org

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
?>

There is another thread talking about this: Manipulate an Archive in memory with PHP (without creating a temporary file on disk)

nettle has suggested to use zip.lib.php from phpmyadmin . I think this is a rather solid solution.

FYI zip.lib.php does not exist anymore, it has been replace by ZipFile.php in the same libraries/ folder.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM