Edited at

PHP 5.6 から ZipArchive::open()の挙動が変わったという話

More than 3 years have passed since last update.


TL;DR

ZipArchive::open() の挙動がPHP5.5と5.6で変わったという話。動作に新規作成を含めるならば、パラメータにZIPARCHIVE::CREATEを入れましょうということ。


詳細

以下のサンプルソースは、カレントディレクトリに hogehoge.zipを作ります。


testZipArch.php

<?php

echo 'Current PHP version: ' . phpversion() . PHP_EOL;
$zip = new ZipArchive();
$zip->open('hogehoge.zip', ZipArchive::OVERWRITE); // PHP 5.5 ならOK
//$zip->open('hogehoge.zip', ZIPARCHIVE::CREATE | ZipArchive::OVERWRITE); // PHP5.5ではNG 5.6ならOK
$zip->addFromString('hoge.csv', 'fuga');
$zip->close();


テスト実行 


PHP5.5 の場合

hogehoge.zipの存在によらず、成功します。

$ php -v                                                                                                     

PHP 5.5.25 (cli) (built: May 15 2015 18:22:49)
Copyright (c) 1997-2015 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2015 Zend Technologies
with Xdebug v2.3.2, Copyright (c) 2002-2015, by Derick Rethans

$ php -m | grep zip
zip

$ php -f testZipArch.php
Current PHP version: 5.5.25

$ ls
testZipArch.php

$


PHP5.6 の場合

hogehoge.zipが存在しない場合、以下のように失敗します。(存在するなら成功します。)

$ php -v

PHP 5.6.20 (cli) (built: Mar 31 2016 07:24:47)
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies
with Xdebug v2.4.0, Copyright (c) 2002-2016, by Derick Rethans

$ php -m | grep zip
zip

$ php -f testZipArch.php
Current PHP version: 5.6.20
PHP Warning: ZipArchive::addFromString(): Invalid or uninitialized Zip object in /var/www/html/hoge/zip/testZipArch.php on line 6
PHP Stack trace:
PHP 1. {main}() /var/www/html/hoge/zip/testZipArch.php:0
PHP 2. ZipArchive->addFromString() /var/www/html/hoge/zip/testZipArch.php:6

Warning: ZipArchive::addFromString(): Invalid or uninitialized Zip object in /var/www/html/hoge/zip/testZipArch.php on line 6

Call Stack:
0.0005 224024 1. {main}() /var/www/html/hoge/zip/testZipArch.php:0
0.0019 224448 2. ZipArchive->addFromString() /var/www/html/hoge/zip/testZipArch.php:6

PHP Warning: ZipArchive::close(): Invalid or uninitialized Zip object in /var/www/html/hoge/zip/testZipArch.php on line 7
PHP Stack trace:
PHP 1. {main}() /var/www/html/hoge/zip/testZipArch.php:0
PHP 2. ZipArchive->close() /var/www/html/hoge/zip/testZipArch.php:7

Warning: ZipArchive::close(): Invalid or uninitialized Zip object in /var/www/html/hoge/zip/testZipArch.php on line 7

Call Stack:
0.0005 224024 1. {main}() /var/www/html/hoge/zip/testZipArch.php:0
0.0020 224352 2. ZipArchive->close() /var/www/html/hoge/zip/testZipArch.php:7

$

但し、コメントに記載したようにZIPARCHIVE::CREATEも使えばPHP5.5の時と同じ動作になります。


解説

要は期待される動作を全てopen()に渡しましょうということです。こんな具合です。

$zip->open('hogehoge.zip', ZIPARCHIVE::CREATE | ZipArchive::OVERWRITE);

ただ、この事自体は http://php.net/manual/ja/ziparchive.open.php#88765 にも書かれていることで、私が環境やバージョンを正確に同定できていないかもです。現在のPHP界隈ではPHP5.5のサポート切れが近づいていることやPHP7のリリースがされたことから、環境の更新を進めているところもあると思います。参考にしていただければ。