Использование ZipArchive с PHP 8 и временными файлами

PHP 8 меняет способ открытия ZIP-архива, и отмечается, что:

Использование пустого файла в качестве ZipArchive не рекомендуется. Libzip 1.6.0 больше не принимает пустые файлы в качестве действительных zip-архивов.

В приведенном ниже тестовом коде открытие ZIP-файла с именем $backupzip работает без ошибок, но открытие ZIP-файла с именем $invoicezip завершается с ошибкой:

Устарело: ZipArchive::open(): использование пустого файла в качестве ZipArchive устарело в строке 12.

<?php
declare(strict_types=1);
ini_set('display_errors','1');ini_set('display_startup_errors','1');error_reporting(E_ALL);
    
define('BACKUPDIR','E:\Database_Backups\\');
$backupfile = BACKUPDIR . date('Ymd') . '.zip';
$temp_file  = tempnam(sys_get_temp_dir(),'AW');

$backupzip  = new ZipArchive();
$invoicezip = new ZipArchive();

$backupzip->open($backupfile,ZipArchive::CREATE);  // <<<--- this works
$invoicezip->open($temp_file,ZipArchive::CREATE);  // <<<--- this fails

person Dave    schedule 05.11.2020    source источник


Ответы (1)


Сбой вызван тем фактом, что использование функции tempnam фактически создает файл с нулевым байтом, и именно на это жалуется ZipArchive::CREATE.

Решение состояло в том, чтобы unlink создать временный файл tempnam перед попыткой его использования. В примере в вопросе я просто добавил unlink($temp_file); сразу после $temp_file = tempnam(sys_get_temp_dir(),'AW');.

Первые несколько строк теперь выглядят так:

<?php
declare(strict_types=1);
ini_set('display_errors','1');ini_set('display_startup_errors','1');error_reporting(E_ALL);
    
define('BACKUPDIR','E:\Database_Backups\\');
$backupfile = BACKUPDIR . date('Ymd') . '.zip';
$temp_file  = tempnam(sys_get_temp_dir(),'AW');
unlink($temp_file);
person Dave    schedule 05.11.2020
comment
Вы также можете использовать ZipArchive::OVERWRITE вместо ZipArchive::CREATE, чтобы временный файл никогда не удалялся. - person drmad; 07.12.2020
comment
Великолепно! Не знаю, как я это пропустил. Спасибо. Гораздо лучше, чем стирание только что созданного временного файла. - person Dave; 07.12.2020