本気でしょうもないハマり方だったんだけど、検索してもこんなショボいこと書いてくれてる人いなかったので、書いておく。

PHP でzipファイルを作ろうとしていた。複数のCSVを一括ダウンロードさせるような、業務系ではわりとよくあるパターンだと思う。

で。せっかくPHPがzipをサポートしてるのにわざわざ zip コマンドを exec() することもないわけで、素直に ZipArchive を使うべきだよね、と。まあそのために –enable-zip したRPMパッケージ作り直す必要があったんだけど、それはいい。

コードは素直にマニュアルにある通り

<?php 
$zip = new ZipArchive; 
$res = $zip->open('test.zip', ZipArchive::CREATE);
if ($res === TRUE) {
    $zip->addFromString('test.txt', 'ここにファイルの内容を書きます');
    $zip->close();
    echo '成功';
} else {
    echo '失敗';
}
?>

だ。もちろんいろいろ違うけど、本質的にはこのまんまだ。

全てが上手く行ったように見えた。日本語のファイル名も大丈夫、データも閲覧できる。と思ったら、Windows のエクスプローラで閲覧できない。フリーソフトのアーカイバではzipファイルの中身を普通に見られるのに、Windows のエクスプローラで閲覧しようとすると、

「フォルダーを開くことができません。圧縮(zip 形式)フォルダー ‘C:/Users/…’ は無効です。」

と文句を言われる。

ネットを検索すると ZipArchive::addFile() での同様の事例が見られた。ディレクトリごと圧縮しようとしている場合に、ハマるらしい。しかし今回はディレクトリなど作っておらず、単純にファイルをほおりこんでいるだけである。解せぬ。

で、結論。

echo 'some message';

みたいのが、いた。俺なんでこんなの残してたんだ。。。なるほど。バイナリエディタでzipファイルを確認すると、先頭に思いっきりASCII文字列で ‘some message’ と書かれていたよ。そうだねこれはzipファイルとしておかしいよねむしろこのおかしな部分を無視してファイルの中身を表示してくれたフリーソフトすごい!

という残念なお話でした。ZipArchive でzipファイルを作成してブラウザに返すときは、余計な応答を返さないように注意しましょう。当たり前すぎてもう何ていうか追っかけてた30分寝てたかった。

こんなくだらないことで苦労する人が減るように。でもこんな間抜けなことする人は僕ぐらいなものかもしれない。