[ PHP ] zip ファイルの作成と展開 ( ZipArchive )

Pocket

PHP 5.2.0 以降デフォルトで使用可能となった ZipArchive クラスを使用して ZIP ファイルの作成および展開のサンプルコードを掲載しています。なお、動作確認は PHP5.3.5 ( Windows ) で行っています。

スポンサーリンク

zip ファイルの作成

ファイルシステム上に一時ファイルとして作成したファイルを ZIP ファイルに追加するサンプルになります。ポイントとして、一時ファイルの削除位置がは ZipArchive::close 関数呼出し後であることです。ZipArchive::close メソッドをコールする前に追加したファイルを削除すると、ZIP ファイルの作成に失敗します。close 時にこれまでの変更を一括で保存する仕様のようです。

// 作成する zip ファイル
$zip_file = '/path/to/file.zip';

$zip = new ZipArchive();
$opened = $zip->open($zip_file, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE);

// テンポラリファイル名の生成
$temp_file = tempnam(sys_get_temp_dir(), 'Tmp');

/*
 * 作成したテンポラリファイルに何か書き込み
 */
$handle = fopen($temp_file, "wb");
fwrite($handle, 'string ・・・');
fclose($handle);

// ファイル(ファイル名:addFile.txt に変更)を zip に追加
$rename = "addFile.txt";
$ret = $zip->addFile($temp_file, $rename);

/*
 * ZIP ファイルのクローズ
 *------------------------------------------------------------------------------
 * これまでの変更を保存する
 */
$ret = $zip->close();

/*
 * 一時ファイルの削除
 *------------------------------------------------------------------------------
 * ZipArchive::close メソッドコール前に削除すると ZIP ファイルの作成に失敗する
 */
$ret = unlink($temp_file);
zip ファイルの解凍・展開

続いて zip ファイルを解凍するサンプルコードになります。展開先のディレクトリが存在しない場合は、自動で作成されます。

$zip_path  = "/path/to/data.zip";      // ZIP ファイルパス
$dest_dir1 = "/path/to/dir1";          // 展開するディレクトリパス(その1)
$dest_dir2 = "/path/to/dir2";          // 展開するディレクトリパス(その2)

$zip = new ZipArchive();
$res = $zip->open($zip_path);
if ($res === true) {

    // 圧縮ファイル内のすべてのファイルを解凍先に展開する場合
    //$zip->extractTo($dest_dir1);

    // 圧縮ファイル内のファイル名を配列で指定して解凍先に展開する
    $zip->extractTo($dest_dir1, array('file1.xls'));
    
    // それぞれ、別ディレクトリに展開することも可能
    $zip->extractTo($dest_dir2, array('file2.txt'));
    
    // zip ファイルを閉じる
    $zip->close();
}
階層違いのディレクトリに同一名のファイルが存在する場合

では、2つのファイルが同一階層で圧縮されている zip ファイルでしたが、 階層違いのディレクトリに同一ファイル名のファイルが存在する場合は、エントリ名が異なるため、そのままファイル名のみを指定することはできません。エントリ名としてファイル名ではなくファイルパスを指定する必要があります。言い換えると、ファイルパスがエントリ名として使用されています。

エントリの一覧表示

以下は、Windows の zip ファイル作成機能で作成した zip ファイル内のエントリを一覧表示するサンプルコードです。

$zip_path = "D:\data.zip"; // ZIP ファイル名
$zip = new ZipArchive();
$res = $zip->open($zip_path);

for($i=0; $i<$zip->numFiles; $i++) {
    echo 'エントリ名 : ' . $zip->getNameIndex($i) . '\n';
}

// 出力結果
// ---------------------------------
// エントリ名 : data/file1.xls
// エントリ名 : data/file2.txt
// エントリ名 : data/subdir/
// エントリ名 : data/subdir/file1.xls
// エントリ名 : data/subdir/file2.txt

ZipArchive::extractTo 関数には、以下のようにエントリ名をパラメータに与えて zip ファイルを展開します。展開も元の階層にあわせて展開され、ディレクトリが存在しない場合は自動で作成されます。

$zip->extractTo($dest_dir1, array('data/subdir/file1.xls', 'data/file2.txt'));
参考

 

スポンサーリンク


Pocket

Leave a Comment

Your email address will not be published. Required fields are marked *