• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:Zend Framework で大きなファイルをダウンロードしたい)

Zend Frameworkで大きなファイルをダウンロードする方法

このQ&Aのポイント
  • Zend Frameworkを使用して大きなファイルをダウンロードする方法を教えてください。
  • http://php.benscom.com/manual/ja/function.readfile.phpを参考に、Zend Frameworkでホームページのバックアップをtarファイル形式でダウンロードしたいと思っています。
  • 数Mbyte程度のファイルはダウンロードできましたが、大きなファイル(200Mbyte)ではエラーが発生しました。ファイルを途中で切れずにダウンロードする方法はありますか?

質問者が選んだベストアンサー

  • ベストアンサー
  • tany180sx
  • ベストアンサー率63% (239/379)
回答No.4

いちおZF-1.9.3にして試してみましたが同様で、 file_get_contents() => メモリサイズエラー fread() => 128MB保存(尻切れ) ob_end_clean() -> fread() => 170MB完全保存 となりました。 出力バッファリングのOFFは ob_end_clean() で可能です。 出力バッファリングが開始されていないと、このコールでエラーとなります。 ob_end_clean() は出力の前で呼んでますよね? 私のアドバイスはこの辺までかな...

noname#207939
質問者

お礼

最初から >出力バッファリングが制限をうけている気がします? とコメントをもらっていたのに、Zend Framework(上での出力バッファリング)を理解できていないようで、お手間を取らせてしまいました。たいへん申し訳ありません。 本当にありがとうございました。

noname#207939
質問者

補足

次のようにしたらダウンロードできました。 public function DownloadAction(){  $file = "test.bin";  $this->_helper->viewRenderer->setNoRender();  $response = $this->getResponse();  $response->clearAllHeaders();  $response->clearBody();  $response->setRawHeader('Content-Description: File Transfer');  $response->setRawHeader('Content-Type: application/octet-stream');  $response->setRawHeader('Content-Disposition: attachment; filename='.basename($file));  $response->setRawHeader('Content-Transfer-Encoding: binary');  $response->setRawHeader('Expires: 0');  $response->setRawHeader('Cache-Control: must-revalidate, post-check=0, pre-check=0');  $response->setRawHeader('Pragma: public');  $response->setRawHeader('Content-Length: ' . filesize($file));  $response->sendHeaders();  $response->setBody(ob_end_clean());  $response->setBody(flush());  $response->outputBody();  $handle = fopen($file, "rb");  $contents = '';  while (!feof($handle)) {   $contents = fread($handle, 8192);   $response->setBody($contents);   $response->outputBody();  }  fclose($handle);  return; }

その他の回答 (3)

  • tany180sx
  • ベストアンサー率63% (239/379)
回答No.3

一応うちの環境では出力バッファリングOFFで最後まで出力できたのですが.. CentOS、PHP5.2.8、ZF1.9.? ソースは追ってないですがdispatchで出力バッファリングが開始されるのでは。 ResponseのoutputBodyはただechoするだけなので バッファリングが有効だと全部蓄えられていくことになります。 Framework通さずに同様の処理をさせると動作しますか?

noname#207939
質問者

補足

コメントありがとうございます。 次の2つでテストしています。 (ローカル)WindwosXP, Apache 2.2.11, PHP Version 5.2.9-2, Zend_Version=1.9.2 php.ini : memory_limit = 128M, output_buffering = Off (レンタルサーバー)sixcore, OS Linux , Apache 2.2.3 , PHP 5.1.6 , Zend_Version=1.9.2 php.ini : memory_limit = 30M, output_buffering = 4096 Frameworkを通さない場合として http://php.benscom.com/manual/ja/function.readfile.php の「例1」は、どちらも200Mbyteのファイルを保存できました。 Frameworkの中に「例1」を置いた場合ですが、index.phpやControllerファイルの中の function init() に置いた場合は200byteのファイルを同様に保存できました。 Actionの中に置くとエラーになります。 $contents = fread($handle, 8192);にした場合はファイルが途中で切れてしまったと書きましたが、ローカルでは約120Mbyteで途切れたファイルが作られ、レンタルサーバーでは約30Mbyteで途切れたファイルが作られます。 FrameworkのバッファリングをOFF(?)にできるのでしょうか?

  • tany180sx
  • ベストアンサー率63% (239/379)
回答No.2

出力バッファリングが制限をうけている気がします? $response->sendHeaders(); ob_clean(); ob_end_clean();

noname#207939
質問者

補足

ob_clean(); ob_end_clean(); を入れてみましたがダメでした。これらはZend Frameworkを使わない場合では無いでしょうか?Zend Frameworkがresponseを管理しているので関係無いような気がします。どうすれば良いかはわかりませんが・・。

noname#94983
noname#94983
回答No.1

実際に同じ環境で試してないので想像でしかないが、これ、ひょっとしてサーバーとの接続がタイムアウトで切れている、ということはないだろうか? ブラウザを変えて試してみても同じだろうか。

noname#207939
質問者

補足

エラーは$response->setBody(file_get_contents(&$file));の場合は Fatal error: Allowed memory size of 31457280 bytes exhausted (tried to allocate 183808001 bytes) で、$contents = fread($handle, 8192);の場合は Internal Server Error になります。IEでもFirefoxでも同じです。 ですのでタイムアウトではなく大きなファイルをresponseにどうやって渡すかという事かと思うのですが、わかりません。