###実現したいこと
PHP側でリンクをクリックすると、サーバ側のZipArchiveでリアルタイムでディレクトリをZip化し、ダウンロードしたいと考えています。
現状でわかっていることが、Zip化したいディレクトリが画像を扱うので、フォルダサイズが大きくなりZip化に時間がかかっているということです。
実行⇒Zip化開始⇒ブラウザ側タイムアウト⇒Zip化終了
という状態を確認できています。
このタイムアウトを回避したいです。
###ソース
PHP
1<?php 2namespace My; 3 4//処理制限時間を外す 5set_time_limit(0); 6 7/** 8 * ZipArchiveを拡張して、ディレクトリまるまる扱う機能を追加 9 */ 10class MyZipArchive extends \ZipArchive 11{ 12 /** 13 * ディレクトリをまるごとzipファイルにします。 14 * 15 * @param string $dir ディレクトリパス 16 * @param string $inner_path zipファイル中のディレクトリパス 17 * @param bool $create_empty_dir 空ディレクトリもディレクトリを作成するか 18 * @return bool 処理の成否 19 */ 20 public function addDir($dir, $inner_path, $create_empty_dir=false){ 21 $items = \array_diff(\scandir($dir), ['.','..']); 22 $item_count = \count($items); 23 24 if($create_empty_dir || $item_count > 0){ 25 $this->addEmptyDir($inner_path); 26 } 27 28 // 追加するものがないならここで終了する 29 if($item_count === 0) return true; 30 31 32 foreach($items as $_item){ // forで行うなら$itemsは一旦array_values()を通したほうがいい 33 $_path = $dir . DIRECTORY_SEPARATOR . $_item; 34 $_item_inner_path = $inner_path . DIRECTORY_SEPARATOR . $_item; 35 36 // ディレクトリの場合は再帰的に処理する 37 if(\is_dir($_path)){ 38 $_r = \call_user_func( // "$this->addDir"より保守的に好ましい 39 [$this, __FUNCTION__], $_path, $_item_inner_path); 40 if(!$_r) return false; 41 } 42 // ファイルの場合でかつ処理に失敗したときはこちら 43 else if(!$this->addFile($_path, $_item_inner_path) 44 && !$this->on_recursive_error($dir, $inner_path, $create_empty_dir)){ 45 return false; 46 } 47 // ファイルの追加成功時は何も他には行わない 48 } 49 50 return true; 51 } 52 53 /** 54 * 再帰的処理のときにエラーが生じたらどうするかを定義しています。 55 * 56 * @param string $parent_dir ディレクトリパス 57 * @param string $parent_inner_path zipファイル中のディレクトリパス 58 * @param bool $create_empty_dir 空ディレクトリもディレクトリを作成するか 59 * @return bool Falseならその場で中断 60 */ 61 private function on_recursive_error($parent_dir, $parent_inner_path, $create_empty_dir){ 62 // 自由に定義してください 63 return false; 64 } 65} 66 67 68/* 69 * 下記は、質問本文のコードをちょっと改造してのテスト 70 */ 71 72//Zipクラスロード 73$zip = new MyZipArchive(); 74 75//Zipファイル名指定 76$zipFileName = '***.zip'; 77 78//Zipファイル一時保存ディレクトリ取得 79$zipTmpDir = './'; 80 81// Zipファイルのパス 82$zip_file = $zipTmpDir . DIRECTORY_SEPARATOR . $zipFileName; 83 84//Zipファイルオープン 85$result = $zip->open($zip_file, \ZIPARCHIVE::CREATE | \ZIPARCHIVE::OVERWRITE); 86 87if ($result !== true) { 88 return false; 89} 90 91 92// ※今回の肝 93$zip->addDir('csv', 'csv', true); 94$zip->addDir('images', 'images', true); 95 96$zip->close(); 97 98 99// ストリームに出力 100header('Content-Type: application/zip; name="' . $zipFileName . '"'); 101header('Content-Disposition: attachment; filename="' . $zipFileName . '"'); 102header('Content-Length: '.filesize($zip_file)); 103echo file_get_contents($zip_file); 104 105// 一時ファイルを削除しておく 106unlink($zip_file); 107exit(); 108?> 109
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。