5

当然,其他一些人已经在 stackoverflow 上讨论了这些问题,但并非所有分析器都适合我,而且他们通常不提供 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

根据文件的内容,我使用了两种方法。对于 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_reportingPHPExcel 写入流有关。

我使用的另一种方法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 回答