PHP:使用 ZipArchive 创建 zip 文件时出现错误 (500)

Posted

技术标签:

【中文标题】PHP:使用 ZipArchive 创建 zip 文件时出现错误 (500)【英文标题】:PHP: Error (500) when creating a zip file with ZipArchive 【发布时间】:2016-01-11 17:18:20 【问题描述】:

我正在使用 phps ZipArchive 类来创建目录的 zip 文件。该代码适用于几乎所有目录,除了两个,这恰好是最大的目录(最大的目录目前包含 51 个文件,总共 175MB)。当我为这些目录运行代码时,将创建一个大小为 67,108,864 字节的临时文件('filename.zip.[RandomLettersAndNumbers]',例如'filename.zip.riaab4'),并且脚本会引发内部服务器错误(500)。

到目前为止我尝试过的(大部分在源代码中仍然可见):

增加memory_limit 增加max_execution_time 检查php错误日志:错误日志为空 尝试找到发生错误的确切行:代码执行到$zip_archive->close();

来源:

//Temporary (debugging) START
ini_set("log_errors", 1);
ini_set("error_log", "php-error.log");
error_log("Hello errors.");
ini_set('memory_limit','512M');
set_time_limit(180);
//phpinfo();
//Temporary (debugging) END

//Get selected directory
// --> Code removed
$result['directory'] = 'directory1';    

//Create .zip file
$zip_archive = new ZipArchive();
$ZIP = 'files/'.$result['directory'].'.zip';

if($zip_archive->open($ZIP, ZipArchive::CREATE | ZIPARCHIVE::OVERWRITE) !== TRUE) 
    echo 'Error! Error while creating ZIP Archive.';
    die;


foreach(new DirectoryIterator('files/'.$result['directory']) as $fileInfo) 
    if($fileInfo->isDot()) 
        continue;
    if(file_exists($fileInfo->getPath())) 
        $zip_archive->addFile('files/'.$result['directory'].'/'.$fileInfo->getFilename(), $fileInfo->getFilename());


//Temporary (debugging) START
echo '<br><br><br>';
var_dump($zip_archive->close());
// ## The following lines are not executed!! ##
echo '<br><br><br>';
var_dump($zip_archive->getStatusString());
echo '<br><br><br>';
//Temporary (debugging) END

if($zip_archive->numFiles > 0 && $zip_archive->close() == true)
    $FILE = $ZIP;
else 


我错过了什么吗?如果还有什么我可以尝试的,请告诉我。谢谢。

编辑:我有一个更具体的问题:为什么受影响目录的临时 zip 文件的文件大小都是 67,108,864 字节?这与 php/服务器设置的最大文件大小有关还是可以用 zip 标准/ZipArchive 类来解释?

【问题讨论】:

Apache 还是 nginx?我认为,PHP 工作,但因为服务器不等待 PHP 完成 - 你会看到错误 500 所以,检查服务器错误,而不是 PHP 我正在使用网络托管服务,因此我无法访问实际的网络服务器。服务器错误日志为空(除了一些不相关的“脚本头过早结束”错误)。根据客户服务,没有最大文件大小(可以在我的本地计算机上压缩目录并在服务器上上传压缩文件)并且没有最大执行时间。 这可能是由于文件句柄数量的限制。你能登录$zip_archive-&gt;numFiles()吗?尝试压缩 100 多个小文件,看看是否会抛出错误 500。可以在php手册php.net/manual/en/ziparchive.addfile.php#112044中找到对这个问题的一个很好的描述 有趣的想法(谢谢!),但遗憾的是它并没有解决问题。最大的目录包含 51 个文件。我已将$zip_archive-&gt;addFile(...) 更改为$zip_archive-&gt;addFromString(...),它工作正常(生成 51x 1KB 文件的 zip 文件),因此文件数量应该不是问题。在执行建议的代码并每 5 个文件关闭 ZipArchive 后,一旦临时 zip 文件的文件大小达到 67,108,864 字节,我仍然会收到内部服务器错误。 【参考方案1】:

尝试关闭 ZIP 存档并在每 5 个左右的文件添加到存档后重新打开它。我认为此解决方案解决了内存限制问题。

感谢 MatthewS 提供此解决方案。

【讨论】:

以上是关于PHP:使用 ZipArchive 创建 zip 文件时出现错误 (500)的主要内容,如果未能解决你的问题,请参考以下文章

php使用ZipArchive压缩文件的心得

php ZipArchive 压缩整个文件夹 - 自带ZipArchive类 - PHP递归创建目录压缩包

php ZipArchive 压缩整个文件夹 - 自带ZipArchive类 - PHP递归创建目录压缩包

文件名中带有重音字符的 PHP ZipArchive

PHP下载压缩包文件

PHP扩展类ZipArchive实现压缩解压Zip文件和文件打包下载 && Linux下的ZipArchive配置开启压缩