使用PHP PCL ZIP在许多调用中压缩单个大文件


ZIP a single big file in many calls using PHP PCL Zip

100mb文件-> 10个ZIP呼叫(每个呼叫10mb ZIP) -> 1个ZIP文件

我应该启动10个调用来将单个100 MB的文件添加到Zip文件中(例如每个调用10 MB的压缩)。

问题是我们有一个内存和时间限制的系统(它不会处理超过10到15MB的呼叫)。

压缩一个包含许多调用的大文件是基本思想。

如果需要,我准备提供更多的数据。

您以前试用过PECL Zip吗?

刚刚用以下代码压缩了两个文件,没有任何内存限制问题。时间限制可以重置。我的环境:memory_limit为3MB, max_execution time为20秒。

<?php
set_time_limit(0);
$zip = new ZipArchive();
$zip->open('./test.zip', ZipArchive::CREATE);
$zip->addFile('./testa'); // 1.3 GB
$zip->addFile('./testb'); // 700mb
$zip->close();

注意: set_time_limit()在php <5.4 with save_mode=on


另一种方法是在后台进程中创建zip文件。这避免了可能的memory_limit问题。

下面是一个例子:http://pastebin.com/7jBaPedb

用法:

try {
  $t = new zip('/bin', '/tmp/test.zip');
  $t->zip();
  if ($t->waitForFinish(100))
    echo "Succes :)";
  else
    echo $t->getOutput();
} catch ($e) {
  echo $e->getMessage();
}

不必等到进程结束,您可以在数据库中写入pid,并在进程结束时提供文件…

阅读你的问题,我首先开始创建一个块zip包装,做你所要求的。它将生成一个数组,其中包含指向网页的链接,您必须按顺序打开这些链接以创建zip文件。当这个想法行得通的时候,我很快意识到它并不是真的需要。

内存限制只在打包程序试图一次打开整个文件,然后将其压缩时才会出现问题。幸运的是,一些聪明的人已经意识到分块做会更容易。

Asbjorn Grandt是创建这个zip类的人之一,它非常容易使用,并且可以满足您的需要。

首先我创建了一个非常大的文件。它的大小为500MB,其中包含各种字母。这个文件是一次性返回处理的,这会导致致命的内存限制错误。

<?php
$fh = fopen("largefile.txt", 'w');
fclose($fh);
$fh = fopen("largefile.txt", 'ab');
$size = 500;
while($size--) {
  $l = chr(rand(97, 122));
  fwrite($fh, str_repeat($l, 1024*1024));
}
fclose($fh);
?>

要使用zip类,我们可以这样做:

<?php
include('zip.php');
$zip = new Zip();
$zip->setZipFile("largefile.zip");
//the firstname is the name as it will appear inside the zip and the second is the filelocation. In my case I used the same, but you could rename the file inside the zip easily.
$zip->addLargeFile("largefile.txt", "largefile.txt");
$zip->finalize();
?>

现在在我的服务器上只需要几秒钟就可以创建大的zip文件,结果是一个550KB的文件。

现在,如果出于一些奇怪的原因,你仍然需要在几个web请求中这样做,请告诉我。我仍然有我开始做这些的代码