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を使う際は、用心したほうがよさそうだ。