Archive_Zipのサブディレクトリごと圧縮

 PHPPEAR)の、Archive_Zipを使った圧縮。


「サブディレクトリごと圧縮ができない」と書かれてる方がいて、それを実現するための独自ルーチンまで作られてるので、「ありゃ、厄介だな」と思いましたが、念のため試しに普通に試してみたら、普通にサブディレクトリごと圧縮できちゃったんですが…。
http://blog.gajapa.jp/?e=32
 どうして人様のところでできず、自分のところでできるのか、なんか不安です。バージョンもArchive_Zip 0.1.1 (beta) で同じなのに…。実はできてないんじゃないかと目を皿にしてためつすがめつあちこち眺めまわしましたが、別に普通にできてます…。


 それに、クラスのコードの中身見るとちゃんと

          // ----- Recursive call to _addFileList()

があるんで、少なくとも「サブディレクトリごと圧縮」しようとはしてるんですよね。それがうまくいってるかいってないかは別として。(うちではうまくいっているように見える)


 うちのアプリケーションコードはこんな感じです↓ PHPハンガリアン記法とかwwwww というツッコミは何卒ご容赦願います…Cプログラマくずれのオヤジなもんで…。アレルギーのある方スマンデス)

	//ディレクトリのローカルパス (NFC)
	$sPathDirLocalNFC = mb_convert_encoding($sPathDirLocalSJIS, 'UTF-8', 'SJIS');
	print('<p>' . sBasename($sPathDirLocalNFC) . ' を圧縮しています... ');
	//ZIPファイルのローカルパス
	$sPathZipLocalSJIS = mb_convert_encoding(mb_substr($sPathDirLocalNFC, 0, mb_strlen($sPathDirLocalNFC) - 1) . '.zip', 'SJIS', 'UTF-8');
	//ZIP
	require_once 'lib/Zip.php';
	$oZip = new Archive_Zip($sPathZipLocalSJIS);
	//ディレクトリを圧縮して、圧縮できなかったならエラーを出して除外
	$oOption = array('remove_path' => $sPathDirLocalSJIS); 
	if (!$oZip->create($sPathDirLocalSJIS, $oOption))
	{
	    print('<p>ディレクトリの圧縮に失敗しました</p>');
	    return false;
	}
	print('100%</p>');
  • ここで$sPathDirLocalSJISは、圧縮したいディレクトリの絶対パス(末尾/あり)です。
  • ZIPファイル名をそれと同名+'.zip'にすることを想定してます。
  • 文字エンコーディングが、うちのファイルシステムではSJISPHPではUTF-8なので、mb_convert_encodingがちょっと繁雑になっています。
  • sBasename()は、こないだコード全掲したオレオレbasename(日本語扱える)です。

日本語対応basename関数(PHP) - 南旺理工


 ここで、'remove_path'は、ZIPファイル内に絶対パスが全部入ってしまわないようにするために、このクラスが標準的に提供している機能を普通に利用してます。
 フォルダ名を入れないようにしてる方もいますが、そのためにいちいちchdirするより、フォルダ名を入れたうえで'remove_path'との差分を取らせるほうが「なんとなく」エレガントに感じられます。(好みの問題?)
株式会社ロックオン社員ブログ | 大阪市北区に本社を置く、ベンチャー企業株式会社ロックオン!「アドエビス」「EC-CUBE」「THREe」など、多くのNo.1製品を輩出する会社の裏側をお見せします。


 う〜む、どこかに落とし穴があるんでしょうか…?
 まいっか、ユーザーにデバッグしてもらお!(爆)

追記

 なんか、このArchive_Zip、巷には2つのバージョンが最新の顔して出回っているっぽい。コード冒頭のバージョン番号が違う。

  • // $Id: Zip.php,v 1.2 2005/11/21 06:51:57 vblavet Exp $
  • // $Id: Zip.php,v 1.16 2008/11/13 04:14:35 clockwerx Exp $

 僕が使ってるのはv 1.2のほうです。両者のコードの中身を見ると、かなり違ってますので、上記の悩んでる方は、v 1.16のほうを使われてるのかもしれませんね。(どうして、バージョン番号小さいほうが日付新しいのはなぜなんだぜ?)
 ちなみに、コードの中には「0.1.1 (beta)」なんて一言も書いてませんでした。v 1.2をダウンロードした配布サイト
Archive_Zip
にそう書いてあったんで、それを写しただけという…すみませんでした。

追記2

 なんか、奥深く潜って更新履歴のページへ行くと、
http://cvs.php.net/viewvc.cgi/pear/Archive_Zip/Archive/Zip.php?diff_format=u&view=log
Revision 1.17が現れ、ダウンロードできます(コード冒頭には「1.16」と書いてありますが)。
 それと、1.16はよく考えたら小数点以下の「いちろく」じゃなく「十六」ですので、1.2より新しいのは当たり前でした。てぃひっ

追記3

 すいません意味わかりました。
 Windows標準のZIPフォルダ機能や、Windows標準のZIP展開機能で見ると、Archive_ZIPにディレクトリを食わせて作ったZIPファイルは、空っぽに見えるんですね。
 Explzhでやってたんで、ぜんっぜん! 気づきませんでした。