这对某些人来说可能很明显,但我忽略了它。
如果您要将要删除的文件添加到 zip 文件中,请确保在调用 close() 函数后删除它们。
如果添加到对象的文件在保存时不可用,则不会创建 zip 文件。
(PHP 5 >= 5.2.0, PHP 7, PHP 8, PECL zip >= 1.1.0)
ZipArchive::close — 关闭活动存档(已打开或新创建)
关闭已打开或创建的存档并保存更改。此方法在脚本结束时自动调用。
如果存档不包含任何文件,则默认情况下该文件将被完全删除(不写入空存档),这取决于ZipArchive::AFL_CREATE_OR_KEEP_FILE_FOR_EMPTY_ARCHIVE
全局标志的值。
此函数没有参数。
这对某些人来说可能很明显,但我忽略了它。
如果您要将要删除的文件添加到 zip 文件中,请确保在调用 close() 函数后删除它们。
如果添加到对象的文件在保存时不可用,则不会创建 zip 文件。
如果您要将多个文件添加到 zip 中,并且您的 $zip->close() 调用返回 FALSE,请确保您添加的所有文件都实际存在。显然,即使文件实际上不存在,$zip->addFile() 也会返回 TRUE。在对文件调用 $zip->addFile() 之前,最好使用 file_exists() 或 is_readable() 检查每个文件。
ZipArchive.close() 在 PHP7 中改变了它的行为。该函数在 PHP5 中忽略目录,但在 PHP7 中会失败,并出现以下错误:
意外的 PHP 错误 [ZipArchive::close(): 读取错误:是一个目录]
以下代码在 PHP5 中有效,但在 PHP7 中无效:
<?php
// test.php
$zip = new ZipArchive();
$zip->open('/tmp/test.zip', ZipArchive::CREATE);
$zip->addFile('.', '.');
$ret = $zip->close();
echo "Closed with: " . ($ret ? "true" : "false") . "\n";
?>
对于 php5
php --version
PHP 5.5.38-1-avature-ondrej-fork (cli) (built: Aug 31 2016 16:37:38)
php test.php
Closed with: true
对于 php7
php --version
PHP 7.0.8-0ubuntu0.16.04.2 (cli) ( NTS )
php test.php
Closed with: false
我不确定,但似乎如果在 $zip->open 中指定的路径是相对路径而不是绝对路径,则 $zip->close() 可能会遇到错误。
因此,在创建存档时,请为要创建的 zip 文件指定绝对路径,而不是相对路径。
如果您已经创建了一个 zip 文件并向其中添加了一个文件,没有出现错误,但是 ZipArchive::close 调用失败(并出现 ER_TMPOPEN: "创建临时文件失败" 错误)并且没有创建 zip 文件,请检查您的 ZipArchive::open 调用是否指定了一个包含不存在目录的路径名。如果您期望一个包含一个或多个目录的层次结构,您必须在使用 ZipArchive 之前自己创建这些目录。您可以编写一个简单的函数来使用 dirname 递归查找每个父目录,在离开递归时使用 mkdir 创建不存在的目录。
不要忘记检查 zip 是否为空,否则 zip 根本不会创建,并且服务器不会发出任何警告!
我使用了一个循环将文件添加到 zip 中,并且在意识到循环最终没有添加任何文件之前,我在权限和文档方面苦苦挣扎了好几个小时,即使调用了 addFile,但调用的是一个不存在的文件。
这可能是您的 zip 无法显示的原因。
请注意,ZipArchive::addFile() 只会打开文件描述符,不会压缩它。只有 ZipArchive::close() 才会压缩文件,并且需要相当长的时间。请注意超时。