here is a little code I wrote:
file_put_contents('a.upl', '');
try
{
$x = new \ZipArchive();
$x->open('a.upl');
}
catch(\Exception $e)
{
echo $e->getMessage();
}
it throws a ZipArchive::open(): Using empty file as ZipArchive is deprecated
message, which is not surprising.
What suprising is, this a.upl
file gets deleted, which is a little bit strange. Why does it do that? And how to prevent this "x-files, magic"?
Did some poking around in the source, sequence of events is this:
PHP sees the file you gave is empty, the latest version of libzip doesn't allow this, so in preparation for this BC break, PHP sets the ZIP_TRUNCATE
flag when calling libzip's zip_open
https://github.com/php/php-src/blob/master/ext/zip/php_zip.c#L1500
libzip, on receiving this flag, creates a new zip object in memory, linked to this file as the source.
When you then add no files to this and the script exits, libzip calls zip_close, and because the ZIP_TRUNCATE
flag is set and there are no entries in the zip, the source file is removed.
https://github.com/nih-at/libzip/blob/cf7bf43ba2f85f936705231903aa0d5cfb2fdf11/lib/zip_close.c#L68
You can avoid the x files magic by setting this global flag: https://www.php.net/manual/en/zip.constants.php#ziparchive.constants.afl-create-or-keep-file-for-empty-archive (if your version of libzip is >=1.10)