質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

サーバ

サーバは、 クライアントサーバモデルにおいてクライアントからの要求に対し 何らかのサービスを提供するプログラムを指す言葉です。 また、サーバーソフトウェアを稼動させているコンピュータ機器そのもののことも、 サーバーと呼ぶ場合もあります。

zip

ZIPとは、複数のファイルをひとつにまとめて圧縮したり、圧縮したファイルを展開することができるアーカイブフォーマットです。 1998年以降のWindowsOS各バージョンで、標準の圧縮フォルダとして採用されています。 MacOSでも、X v10.3以降に他の圧縮ソフトとまとめてZIP機能を採用しています。

Q&A

1回答

1477閲覧

ZipArchive使用時のタイムアウト

Zu_Chan

総合スコア14

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

サーバ

サーバは、 クライアントサーバモデルにおいてクライアントからの要求に対し 何らかのサービスを提供するプログラムを指す言葉です。 また、サーバーソフトウェアを稼動させているコンピュータ機器そのもののことも、 サーバーと呼ぶ場合もあります。

zip

ZIPとは、複数のファイルをひとつにまとめて圧縮したり、圧縮したファイルを展開することができるアーカイブフォーマットです。 1998年以降のWindowsOS各バージョンで、標準の圧縮フォルダとして採用されています。 MacOSでも、X v10.3以降に他の圧縮ソフトとまとめてZIP機能を採用しています。

0グッド

0クリップ

投稿2017/12/13 01:22

###実現したいこと
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

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

えっと、非同期通信します。

まず、非同期でZip圧縮処理を叩いて、バックグラウンドで圧縮処理を走らせます。
その圧縮処理では進行状況をログに出力します。

一方、別の非同期通信で、さっきのログを読んで圧縮が終わったか確認し続けます。
圧縮が終わっていたら、晴れて、ファイルをダウンロードします。

以上ですん。

投稿2017/12/13 02:35

編集2017/12/13 02:37
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問