我正在尝试在用户点击下载链接时下载文件。
在控制器中:
$response = new Response();
$response->headers->set('Content-type', 'application/octect-stream');
$response->headers->set('Content-Disposition', sprintf('attachment; filename="%s"', $filename));
$response->headers->set('Content-Length', filesize($filename));
return $response;
这是打开保存文件的对话框,但它说该文件是0字节。 并将其更改为:
$response = new Response();
$response->headers->set('Content-type', 'application/octect-stream');
$response->headers->set('Content-Disposition', sprintf('attachment; filename="%s"', $filename));
$response->headers->set('Content-Length', filesize($filename));
$response->headers->set('Content-Transfer-Encoding', 'binary');
$response->setContent(readfile($filename));
return $response;
我得到了一堆奇怪的字符,而不是文件下载对话框。
最后,将“setContent”行切换为:
$response->setContent(file_get_contents($filename));
它返回PHP错误:
致命错误:允许的内存大小......
有关如何实现这一目标的任何线索? 我之前在PHP中做过(没有MVC),但我不知道通过Symfony2可以做些什么......
也许解决方案是在PHP.INI中设置memory_limit,但我想这不是最好的做法......
答案 0 :(得分:81)
最舒适的解决方案是
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
$response = new BinaryFileResponse($file);
$response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT);
return $response;
答案 1 :(得分:46)
首先,感谢大家的回复。我终于在没有X-SendFile的情况下解决了这个问题(这可能是最好的做法)。无论如何,对于那些无法让X-Sendfile apache模块工作的人(共享主机),这里有一个解决方案:
// Generate response
$response = new Response();
// Set headers
$response->headers->set('Cache-Control', 'private');
$response->headers->set('Content-type', mime_content_type($filename));
$response->headers->set('Content-Disposition', 'attachment; filename="' . basename($filename) . '";');
$response->headers->set('Content-length', filesize($filename));
// Send headers before outputting anything
$response->sendHeaders();
$response->setContent(file_get_contents($filename));
return $response;
希望这有帮助!
答案 2 :(得分:13)
您不应该使用PHP来下载文件,因为它是Apache或Nginx服务器的任务。最好的选择是使用X-Accel-Redirect(在Nginx的情况下)/ X-Sendfile(在Apache的情况下)头文件下载。
以下操作代码段可与配置的Nginx一起使用,以便从Symfony2下载文件:
return new Response('', 200, array('X-Accel-Redirect' => $filename));
UPD1:配置了mod_xsendfile的apache代码:
return new Response('', 200, array(
'X-Sendfile' => $filename,
'Content-type' => 'application/octet-stream',
'Content-Disposition' => sprintf('attachment; filename="%s"', $filename))
));
答案 3 :(得分:7)
不知道它是否有帮助,但它是application/octet-stream
而不是application/octect-stream
答案 4 :(得分:7)
从Symfony 3.2开始,您可以使用file() controller helper,这是创建BinaryFileResponse
的快捷方式,如上一个答案所述:
public function fileAction()
{
// send the file contents and force the browser to download it
return $this->file('/path/to/some_file.pdf');
}
答案 5 :(得分:6)
+1亚历山大回应。
但是如果你不能使用X-Sendfile,你应该使用2.2中添加的BinaryFileResponse:http://symfony.com/doc/current/components/http_foundation/introduction.html#serving-files
在我的项目中,结果是
$response = new \Symfony\Component\HttpFoundation\BinaryFileResponse($dir .DIRECTORY_SEPARATOR. $zipName);
$d = $response->headers->makeDisposition(
ResponseHeaderBag::DISPOSITION_ATTACHMENT,
$zipName
);
$response->headers->set('Content-Disposition', $d);
return $response;
答案 6 :(得分:1)
对于那些不能设置标题的人:
download
属性可能有所帮助,具体取决于您需要支持的浏览器:
<a href="{file url}" download>
或
<a href="{file url}" download="{a different file name}">
所有旧版浏览器都不支持此功能。有关浏览器支持,请参阅此页面: