3
3

More than 3 years have passed since last update.

ZipArchiveで突然"ZipArchive::addFromString(): Invalid or uninitialized Zip object"が出る様になった話

Last updated at Posted at 2020-02-03

はじまり

ZipArchiveで以下の様なコードを実行していたが、yum update でPHP等のアップデートを行ってから急にZipArchive::addFromString(): Invalid or uninitialized Zip object が出て正常に動作しないようになった。

<?php
$zip = new ZipArchive;
$zip->open(tempnam(sys_get_temp_dir(), 'foo-'), ZipArchive::CREATE);
$zip->addFromString('bar.txt', 'hogehoge');
$zip->close();

調べてみると $zip->open() の部分で失敗している様子。

原因の調査

PHPの確認

アップデート前のサーバがたまたまあったので、適当なコードを書いて比較してみることにした。
CentOS 7でPHPはremi-php72でインストール。

検証用コード
<?php
$zip = new ZipArchive;
var_dump($zip->open(tempnam(sys_get_temp_dir(), 'foo-'), ZipArchive::CREATE));
var_dump($zip->open(sys_get_temp_dir().'foo.zip', ZipArchive::CREATE));

PHP 7.2.26

$ php test.php
bool(true)
bool(true)

どちらも通る。

PHP 7.2.27

$ php test.php
int(19) 
bool(true)

tempnam()を使っている方が通らなくなった。
int(19) はzip archiveでは無いファイルを開こうとした場合に返ってくるエラーコードの模様。しかし、そもそも空のファイルのはず…

PHPのソースコードでzip関連のコミットログを追いかけて見るも怪しい箇所は見つからず。PHPでは無くlibzipに原因があるのかもと思い確認してみる。

libzipの確認

PHP 7.2.26

# yum list installed php libzip5
libzip5.x86_64                   1.5.2-1.el7.remi                    @remi-safe
php.x86_64                       7.2.26-1.el7.remi                   @remi-php72

PHP 7.2.27

# yum list installed php libzip5
libzip5.x86_64                   1.6.0-1.el7.remi                    @remi
php.x86_64                       7.2.27-1.el7.remi                   @remi-php72

GitHubのリポジトリで変更内容を確認する。

1.6.0 [2020-01-24]

Avoid using umask() since it's not thread-safe.
Set close-on-exec flag when opening files.
Do not accept empty files as valid zip archives any longer.
Add support for XZ compressed files (using liblzma).
Add support for cancelling while closing zip archives.
Add support for setting the time in the on-disk format.

ん…?

Do not accept empty files as valid zip archives any longer.
Do not accept empty files as valid zip archives any longer.
Do not accept empty files as valid zip archives any longer.

該当部分の変更内容を確認するかぎり、libzipの仕様が変更になったとわかる。

まとめ

ZipArchiveの使い方によっては不具合が出る場合がある。ただしバグではなく仕様変更なので元に戻ることは期待できない。
…と思っていたらPHP 7.4.5で対応されたようだ。PHP 7.2系には現時点でバックポートされていないが、そのうち対応されるのかも。

ダメでした。PHP 8より後で正式に非対応となることが決まったようです。https://www.php.net/manual/ja/migration80.deprecated.php#migration80.deprecated.zip

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3