5

当然のことながら、他の何人かの人々はスタックオーバーフローでこれらの問題について議論しましたが、すべての回答が私のために働くわけではなく、しばしば彼らはそこのsymfonyインストールのバージョンを提供しません。

私が読んだトピック:

それが、symfony 1.4で(ビューを使用せずに)ファイルのダウンロードをどのように処理するかを尋ねるポイントですか?すべてのユースケースで、応答をレンダリングするためのテンプレートファイルが必要です。コントローラに起因する応答を送信する場合、phpエラーなしで応答を送信する唯一の可能性があります(ヘッダーはすでに送信されています)。

コントローラ:

/** @var $response sfWebResponse */
$response = $this->getResponse();
$response->clearHttpHeaders();
$response->setContentType($mimeType);
$response->setHttpHeader('Content-Disposition', 'attachment; filename="' . basename($filePath) . '"');
$response->setHttpHeader('Content-Description', 'File Transfer');
$response->setHttpHeader('Content-Transfer-Encoding', 'binary');
$response->setHttpHeader('Content-Length', filesize($filePath));
$response->setHttpHeader('Cache-Control', 'public, must-revalidate');
$response->setHttpHeader('Pragma', 'public');
$response->sendHttpHeaders();

readfile($filePath); die();

これは、テンプレートファイルなしで機能します。しかし、これはそれほどきれいなコーディングではありません。

テンプレートを使用した別の方法:

コントローラ:

 /** @var $response sfWebResponse */
$response = $this->getResponse();
$response->clearHttpHeaders();
$response->setContentType($mimeType);
$response->setHttpHeader('Content-Disposition', 'attachment; filename="' . basename($filePath) . '"');
$response->setHttpHeader('Content-Description', 'File Transfer');
$response->setHttpHeader('Content-Transfer-Encoding', 'binary');
$response->setHttpHeader('Content-Length', filesize($filePath));
$response->setHttpHeader('Cache-Control', 'public, must-revalidate');
$response->setHttpHeader('Pragma', 'public');
$response->setContent(file_get_contents($filePath));
$response->sendHttpHeaders();

return sfView::NONE;

見る:

<?php echo $sf_response->getRawValue()->getContent(); ?>
4

3 に答える 3

6

私の好みの解決策

$filePath = $document->getAbsoluteFilePath();
$mimeType = mime_content_type($filePath);

/** @var $response sfWebResponse */
$response = $this->getResponse();
$response->clearHttpHeaders();
$response->setContentType($mimeType);
$response->setHttpHeader('Content-Disposition', 'attachment; filename="' . basename($filePath) . '"');
$response->setHttpHeader('Content-Description', 'File Transfer');
$response->setHttpHeader('Content-Transfer-Encoding', 'binary');
$response->setHttpHeader('Content-Length', filesize($filePath));
$response->setHttpHeader('Cache-Control', 'public, must-revalidate');
// if https then always give a Pragma header like this  to overwrite the "pragma: no-cache" header which
// will hint IE8 from caching the file during download and leads to a download error!!!
$response->setHttpHeader('Pragma', 'public');
//$response->setContent(file_get_contents($filePath)); # will produce a memory limit exhausted error
$response->sendHttpHeaders();

ob_end_flush();
return $this->renderText(readfile($filePath));

テンプレートファイルを使用する必要はありません。symfonyの標準的な振る舞いの使用。重要:テンプレートファイルが存在する必要があります!

于 2013-01-22T11:02:00.360 に答える
1

ファイルの内容に応じて、2つの方法を使用しました。Excelドキュメントなどのドキュメントの場合、私は通常このアプローチを使用します。

$this->getResponse()->clearHttpHeaders();
$this->getResponse()->setHttpHeaders('Content-Description','File Transer');
$this->getResponse()->setHttpHeaders('Content-Type','application/vnd.ms-excel'); //this would be based on your file
$this->getResponse()->setHttpHeaders('Content-Disposition','attachment;filename='.$filename); //$filename is name of file on server
$this->getResponse()->setHttpHeaders('Pragma','');
$this->getResponse()->setHttpHeaders('Cache-Control','');
$this->getResponse()->sendHttpHeaders();

$error_reporting = error_reporting(0);
$this->renderText($some_data->save('php://output')); //in this case the $some_data was a PHPExcel writer object but anything that can be saved to a [php://output][1] should work e.g. fwrite()
error_reporting($error_reporting);
return sfView::NONE

スイッチのerror_reportingオフとオンは、PHPExcelを使用してストリームに書き込むことと関係がありました。

私が使用した他の方法は、のsendContent()方法を使用しsfResponseます。この使用例は次のとおりです。

$this->getResponse()->clearHttpheaders();
$this->getResponse()->setHttpHeader('Content-Description','File Transfer');
$this->getResponse()->setHttpHeader('Cache-Control', 'public, must-revalidate, max-age=0');
$this->getResponse()->setHttpHeader('Pragma: public',true);
$this->getResponse()->setHttpHeader('Content-Transfer-Encoding', 'binary'); 
$this->getResponse()->setHttpHeader('Content-length',filesize($filename)) //send the size of the file
$this->getResponse()->setHttpHeader('Content-Type','some_mime_type') // e.g. application/pdf, image/png etc.
$this->getResponse()->setHttpHeader('Content-Disposition','attachment; filename='.$filename) //some filename
$this->getResponse()->sendHttpHeaders(); //edited to add the missed sendHttpHeaders
$this->getResponse()->setContent(readfile($filename));

$this->getResponse()->sendContent();

return sfView::NONE;

どちらのアプローチも機能し、コンテンツ/ファイルをレンダリングするためのテンプレートは必要ありません。

注:$this->getResponse()->sendHttpHeaders()コンテンツを設定して送信する前に追加するように編集しました

于 2013-01-03T18:50:13.940 に答える
0

プレーンなphp関数でもそれを行うことができます:

public function executeIndex(sfWebRequest $request)
{
  while(ob_get_level())
  {
    ob_end_clean();
  }

  // use plain php functions to
  // setup headers
  // ...
  // and read and echo the file

  throw new sfStopException();
}
于 2013-01-03T23:05:03.533 に答える