2008年1月27日日曜日

PHPでファイルを zipするためのサンプルと 4つの注意点

PHPでzipするサンプルと注意点。


注意点
  • (Windowsの場合) php.iniの、extension=php_zip.dllのコメントアウトを外しておかないと、「Fatal error: Class 'ZipArchive' not found」が出る。
  • zipのopen時に、
    • ZIPARCHIVE::CREATEを指定すると、指定したパスにまだzipが無い場合は新規作成し、既にzipがある場合はそのzipに各ファイルが追加される。
    • ZIPARCHIVE::OVERWRITEを指定すると、常にzipを新規作成する。既存のzipがある場合は、zip自体を上書きする。(2009/03/23訂正:仕様が変わり、既存のZIPが無い場合にOVERWRITEを指定するとopen()に失敗するようになった。対策は下記サンプルコードを参照。)
  • zipを展開するクライアントがWindowsの場合、ファイル名はSJISにしないと文字化けする。
  • zipをダウンロードさせる場合、Content-typeに既知の値("application/zip"や"application/x-zip-compressed")を指定すると、IEでダウンロードするとzipを展開できない。なのでContent-typeには存在しない適当な値を指定する。(未知のContent-typeの場合は拡張子からzipであることを推測しているようだ。)
    ただし7-zipでなら開けたので、正しいContent-typeでもzip自体は正しくできているようだ。


サンプルコード
<?php
$zipPath = './test.zip';

//zipをopenする
$zip = new ZipArchive();
$rtn = $zip->open('./test.zip', ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE);
if ($rtn !== true) {
 exit('zip作成に失敗! エラーコード=' . $rtn);
}

//ファイルをzipに追加する
$zip->addFile('./zip.php', 'zip.php'); //ファイルのパスとzip後のファイル名
$zip->addFile('./zip.php', mb_convert_encoding('このPHPのソースファイル.php', 'SJIS'));

//テキストファイルを動的にzipに追加する
$text = " 動的に書いた \n テキストファイル ";
$zip->addFromString('dynamic.txt', $text); //ファイルのパスとその内容

//zipをcloseする
$zip->close();

//zipファイルを出力する
header('Content-type: application/x-zip-dummy-content-type'); //存在しないtypeにする
$zipName = mb_convert_encoding('zipのテスト.zip', 'SJIS');
header('Content-Disposition: attachment; filename=' . $zipName);
echo file_get_contents($zipPath);

(更新履歴)
2009/03/23 openの第2引数を変更


参考:
 PHP: Zip - Manual
 codeなにがし::ブラウザ上でローカルファイルをZIP圧縮 (文字コードについての参考)
 ZIP (ファイルフォーマット) - Wikipedia (Content-typeについての参考。使えなかったが。)

0 件のコメント:

コメントを投稿