ぷろぐらみんぐ帳

C#とかJavaScriptとか

PHPのZipArchiveの日本語を含むディレクトリでハマった話

PHPディレクトリ内のファイルを1つのZipファイルに圧縮しようとしたらハマったときの話。

以下のようなファイル構成である。
-test
└index.php
└data
 -001.txt
 -: :

ここでdataフォルダ以下をtest直下のdata.zipに圧縮したい。index.phpのソースは以下の通り(適当に探して拝借しました)。

<?php
//index.php
$files = glob("data/*.*");

//Zipに圧縮
$zip = new ZipArchive;
$res = $zip->open("data.zip", ZipArchive::CREATE | ZipArchive::OVERWRITE);

if($res === true)
{
    foreach($files as $f)
    {
        $zip->addFile($f, basename($f));
    }
    $zip->close();
}
else
{
    echo "Error Code".$res;
}

シェルを起動し、cdでtestフォルダをルートとして「php -S localhost:8000」でPHPを起動する。ブラウザで「localhost:8000」でindex.phpを読み込ませる。PHPのバージョンは7.0.9、Windows上で実行させた。

この例はこれは普通に成功し、zipファイルができる。addFileで第2引数以下でbasenameとしないと、data.zipの中にさらにdataフォルダができる(要はルートディレクトリ以下のパスが維持される)。

ところがルートを「test」から「テスト」に変えてパスに日本語を含む形にすると上手くは行かない

同様に実行させると、「Error Code18」と表示されzipファイルが生成されない。エラーはZipArchive::openで発生しており、globは正しく取得できている。エラーコードを逆引きすると、「Invalid argument(引数がおかしい)」とのこと。どこがいけないのか数時間ハマった。

PHP: ZipArchive::open - Manual

日本語をパスに含む環境でZipArchiveを使う際は、用心したほうがよさそうだ。