6

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
Dave
  • 5,108
  • 16
  • 30
  • 40

1 Answers1

12

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);
Dave
  • 5,108
  • 16
  • 30
  • 40
  • 18
    You can also use `ZipArchive::OVERWRITE` instead of `ZipArchive::CREATE`, so the temp file is never deleted. – drmad Dec 07 '20 at 12:13
  • Brilliant! Don't know how I missed that. Thank you. Much better than erasing a just created temporary file. – Dave Dec 07 '20 at 18:48