Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-apps-script/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php Symfony 1.4:提供文件下载的最佳方式,无需使用模板/视图_Php_Symfony1_Symfony 1.4 - Fatal编程技术网

Php Symfony 1.4:提供文件下载的最佳方式,无需使用模板/视图

Php Symfony 1.4:提供文件下载的最佳方式,无需使用模板/视图,php,symfony1,symfony-1.4,Php,Symfony1,Symfony 1.4,当然,其他一些人已经在stackoverflow上讨论了这些问题,但并不是所有的ansers都适合我,而且他们通常不提供symfony安装的版本 我阅读的主题: 这就是我要问的问题,您如何处理symfony 1.4中的文件下载(不使用视图)?在我的所有用例中,我都需要一个模板文件来呈现响应。如果我将响应发送到控制器,那么只有在没有php错误(标头已发送)的情况下,才能使用 控制器: /** @var $response sfWebResponse */ $response = $thi

当然,其他一些人已经在stackoverflow上讨论了这些问题,但并不是所有的ansers都适合我,而且他们通常不提供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(); ?>
这在没有模板文件的情况下工作。但我觉得这不是很好的编码

使用模板的替代方法:

控制器:

/** @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(); ?>
查看:

/** @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(); ?>

根据文件的内容,我使用了两种方法。对于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
错误报告
关闭和打开与使用PHPExcel写入流有关

我使用的另一种方法是使用
sfResponse
sendContent()
方法。这种用法的示例如下:

$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()
,您也可以使用普通的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();
}
我喜欢的解决方案

$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标准行为。重要提示:模板文件必须存在

您是否尝试过使用
return$this->renderText($response->getContent())
而不是
返回sfView::NONE
?读取文件的方法比将内容发送到视图要好,因为前者具有内置缓冲,而后者必须完全保存在内存中,因此速度较慢。
return$this->renderText($response->getContent())在我的情况下不起作用。它不会引发异常,但会从浏览器中引发一个“未找到文件”错误。您的第二个解决方案将正常工作,但会在错误日志中填入
PHP警告:无法修改标题信息-标题已发送
消息。因此,这不是一个真正好的解决方案。只有当您在sendContent()之后使用die()退出输出时,才会引发警告。哦,很抱歉,错过了
$this->getResponse()->sendHttpHeaders()
。我对答案进行了编辑,将其包括在内。这不是重点。使用
$this->getResponse()->sendContent()
您将发送头,除非您之前没有发送头,但是使用return语句imho将发送下一个头,然后抛出警告。好的,我不确定您在说什么。我先发送标题,然后再发送内容,没有收到任何PHP错误。你确定你的代码中没有发生其他事情吗?很好。注意模板文件实际上不需要存在。如果您使用模板配置模块,那么它必须存在。只有将它们设置为false或控制器为null,才不需要模板文件,否则将记录警告(之前发送的标题)