这是我写的一些代码:
file_put_contents('a.upl', '');
try
{
$x = new \ZipArchive();
$x->open('a.upl');
}
catch(\Exception $e)
{
echo $e->getMessage();
}
它会抛出一条
ZipArchive::open(): Using empty file as ZipArchive is deprecated
消息,这并不奇怪。
令人惊讶的是,这个a.upl
文件被删除了,这有点奇怪。为什么要这样做?如何防止这种“X档案,魔法”?
在源代码中进行了一些研究,事件顺序是这样的:
PHP 看到你给的文件是空的,最新版本的 libzip 不允许这样做,所以为了准备这个 BC 中断,PHP 在调用 libzip 的
ZIP_TRUNCATE
时设置了
zip_open
标志
https://github.com/php/php-src/blob/master/ext/zip/php_zip.c#L1500
libzip 在收到此标志后,会在内存中创建一个新的 zip 对象,并作为源链接到此文件。
当您不向其中添加任何文件并且脚本退出时,libzip 会调用 zip_close,并且由于设置了
ZIP_TRUNCATE
标志并且 zip 中没有条目,因此源文件将被删除。
https://github.com/nih-at/libzip/blob/cf7bf43ba2f85f936705231903aa0d5cfb2fdf11/lib/zip_close.c#L68
您可以通过设置此全局标志来避免 x 文件魔法:https://www.php.net/manual/en/zip.constants.php#ziparchive.constants.afl-create-or-keep-file-for -empty-archive(如果您的 libzip 版本 >=1.10)