[PHP]ディレクトリー(フォルダ)の階層構造を維持したまま圧縮する

Pocket

ZipArchive クラスを使った単純なファイルの圧縮については前回の記事に書きましたが、ディレクトリーを対象に、そのサブディレクトリも含めて圧縮するには再帰的に処理する工夫が必要です。

<?php
// 圧縮するディレクトリー
$dir = dirname(__FILE__) . '/base/';

// Zipファイルの保存先
$file = './test.zip';

zipDirectory($dir, $file);


// ディレクトリを圧縮する
function zipDirectory($dir, $file, $root=""){
	$zip = new ZipArchive();
	$res = $zip->open($file, ZipArchive::CREATE);

	if($res){
		// $rootが指定されていればその名前のフォルダにファイルをまとめる
		if($root != "") {
			$zip->addEmptyDir($root);
			$root .= DIRECTORY_SEPARATOR;
		}

		$baseLen = mb_strlen($dir);
		
		$iterator = new RecursiveIteratorIterator(
			new RecursiveDirectoryIterator(
				$dir,
				FilesystemIterator::SKIP_DOTS
				|FilesystemIterator::KEY_AS_PATHNAME
				|FilesystemIterator::CURRENT_AS_FILEINFO
			), RecursiveIteratorIterator::SELF_FIRST
		);

		$list = array();
		foreach($iterator as $pathname => $info){
			$localpath = $root . mb_substr($pathname, $baseLen);
		
			if( $info->isFile() ){
				$zip->addFile($pathname, $localpath);
			} else {
				$res = $zip->addEmptyDir($localpath);
			}
		}

		$zip->close();
	} else {
		return false;
	}
}

ディレクトリ内のファイル一覧の作り方に関しては過去の記事のものをもとに少し変更してあります。
関数を使う際は引数として (ディレクトリパス, Zipファイル保存先, 親ディレクトリの名前) を指定します。親ディレクトリの名前は省略可で、指定するとその名前のフォルダがZipファイル内に作られ、ファイルは親フォルダ以下にまとめられます。

zip_root


Similar Posts:




コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です