cakephp zip 作成 ダウンロード
CakePHPでZIPファイルをダウンロードする
主にこのクラスを使って処理をするのだけど
PHP: ZipArchive - Manual
ZipArchiveにディレクトリをzipに含めるというメソッドがない。
ディレクトリを指定して、中身を全部追加したい場合は、
空のディレクトリを作るメソッドと、ファイルを追加するというメソッドを組み合わせて
処理を作る必要がある。
<?php class DownloadController extends AppController { public function zip() { $zip = new ZipArchive(); $zip_dir_path = TMP; $zip_file_name = $this->Session->id().'.zip'; if (!$zip->open($zip_dir_path.$zip_file_name, ZipArchive::CREATE | ZIPARCHIVE::OVERWRITE)) { throw new InternalErrorException(); } // 文字列をファイルにしてzipに追加する場合 if (!$zip->addFromString('string.txt', '文字列をファイルにして追加')) { throw new InternalErrorException(); } // ファイルをzipに追加する場合 if (!$zip->addFile(TMP.'kinoko.jpg', 'image.jpg')) { throw new InternalErrorException(); } // ディレクトリの中を全てzipに追加する場合 $this->addDirectoryToZip($zip, TMP.'dirname'); $zip->close(); $this->autoRender = false; $this->response->type('application/zip'); $this->response->file($zip_dir_path.$zip_file_name, array('download' => true)); $this->response->download('test2.zip'); } // ファイル名一覧を取得する private function getFiles($dir_path) { $files = array(); if(is_dir($dir_path)) { $dh = opendir($dir_path); while($file = readdir($dh)) { if ($file != '.' && $file != '..') { array_push($files, $file); } } closedir($dh); } var_dump($files); return $files; } // ディレクトリをzipに追加する private function addDirectoryToZip($zip, $src_dir_path, $tar_dir_path = '') { // zip 内にディレクトリを作成する if (strlen($tar_dir_path) > 0) { if (!$zip->addEmptyDir($tar_dir_path)) { throw new InternalErrorException(); } } // ディレクトリ内のファイルを取得する foreach ($this->getFiles($src_dir_path) as $file) { $src_file_path = $src_dir_path.'/'.$file; $tar_file_path = strlen($tar_dir_path) > 0 ? $tar_dir_path.'/'.$file : $file; if (is_dir($src_file_path)) { // ディレクトリの場合、中のファイルをzipに追加する $this->addDirectoryToZip($zip, $src_file_path, $tar_file_path); } else { // ファイルをzipに追加する if(!$zip->addFile($src_file_path, $tar_file_path)) { throw new InternalErrorException(); } } } } }
CakePHPの方は
$this->autoRender = false; $this->response->type('application/zip'); $this->response->file($zip_dir_path.$zip_file_name, array('download' => true)); $this->response->download('test2.zip');
Viewを使用しない
Responseがzipであること宣言する
Responseにzipファイルを追加する
ダウンロードさせるファイル名を設定する
という感じで設定しているらしい。
zipを作成するディレクトリとか、削除するタイミングとかを別途考えないといけない。