Symfony2 – 强制文件下载

我试图在用户点击下载链接时下载文件。

在控制器中:

$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做到这一点…

也许解决scheme是在PHP.INI中设置memory_limit,但我想这不是最好的做法…

最舒适的解决scheme是

 use Symfony\Component\HttpFoundation\BinaryFileResponse; use Symfony\Component\HttpFoundation\ResponseHeaderBag; $response = new BinaryFileResponse($file); $response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT); return $response; 

首先,感谢大家的回复。 我终于解决了这个没有X-SendFile(这可能是最好的做法)。 无论如何,对于那些不能让X-Sendfile的apache模块工作(共享主机),这里有一个解决scheme:

 // 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)); 

希望这可以帮助!

您不应该使用PHP下载文件,因为这是Apache或Nginx服务器的任务。 最好的select是使用X-Accel-Redirect(对于Nginx)/ X-Sendfile(对于Apache)头文件下载。

下面的动作片段可以用于configurationNginx从Symfony2下载文件:

 return new Response('', 200, array('X-Accel-Redirect' => $filename)); 

UPD1:configurationmod_xsendfile的apache代码:

 return new Response('', 200, array( 'X-Sendfile' => $filename, 'Content-type' => 'application/octet-stream', 'Content-Disposition' => sprintf('attachment; filename="%s"', $filename)) )); 

不知道它是否可以帮助,但它的application/octet-stream而不是application/octect-stream

亚历山大反应+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; 

从Symfony 3.2开始,您可以使用file()控制器帮助程序 ,它是创buildBinaryFileResponse的快捷方式,如前面的答案中所述:

 public function fileAction() { // send the file contents and force the browser to download it return $this->file('/path/to/some_file.pdf'); } 

对于那些没有select设置标题的人:

download属性可能会有所帮助,具体取决于您需要支持哪些浏览器:

<a href="{file url}" download>

要么

<a href="{file url}" download="{a different file name}">

这在所有旧版浏览器中都不受支持。 浏览器支持请参见此页面:

https://www.w3schools.com/tags/att_a_download.asp