Search code examples
phpphp-ziparchivephp-8

Using ZipArchive with PHP 8 and temporary files


PHP 8 changes how the "open" of a ZIP archive works and it is noted that:

Using empty file as ZipArchive is deprecated. Libzip 1.6.0 do not accept empty files as valid zip archives any longer.

In the test code below the opening of the ZIP file named $backupzip works without error but the opening of the ZIP file names $invoicezip fails with the error:

Deprecated: ZipArchive::open(): Using empty file as ZipArchive is deprecated on line 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

Solution

  • The failure is being caused by the fact that the use of the tempnam function actually creates a zero byte file and that is what ZipArchive::CREATE is complaining about.

    The solution was to unlink the temporary file created by tempnam before trying to use it. In the example in the question I simply added unlink($temp_file); immediately after $temp_file = tempnam(sys_get_temp_dir(),'AW');.

    The first few lines now look like this:

    <?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);