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

时间:2013-05-23 07:20:52

标签: php zip pclzip

100 MB文件 - > 10个ZIP通话(每通话10个邮箱) - > 1个ZIP文件

我应该发起10次调用,将一个100 MB的文件添加到Zip文件中(比如每次调用10 MB的压缩)。

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

因此,通过多次调用来压缩大文件是基本的想法。

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

2 个答案:

答案 0 :(得分:3)

您以前曾尝试过PECL Zip吗?

使用以下代码压缩两个文件,没有任何内存限制问题。时间限制可能会重置。我的环境:memory_limit为3MB,max_execution时间为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&lt; 5.4使用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并在文件完成后提供服务,而不是等到进程结束...

答案 1 :(得分:2)

阅读你的问题我首先开始创建一个分块拉链包装机,按照你的要求做。它会生成一个包含指向网页的链接的数组,您必须按顺序打开它才能创建一个zip文件。虽然这个想法奏效了,但我很快意识到它并非真正需要。

当打包程序尝试一次打开整个文件然后压缩它时,memorylimit只是一个问题。幸运的是,一些聪明的人已经认为以块的形式更容易做到这一点。

Asbjorn Grandt是创造这个zip class的人之一,它非常易于使用,可以满足您的需求。

首先我创建了一个非常大的文件。它的大小为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的文件。

现在,如果出于某种奇怪的原因,您仍需要在多个网络请求中执行此操作,请告诉我们。我仍然有我开始的代码来做这件事。