3

我有一个关于使用 Symfony 2.1 提供文件的问题

public function exampleFileAction(){
    $response = new Response();

    $d = $response->headers->makeDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, 'File.xls');

    $response->setContent(file_get_contents('../uploads/Bundle/Files/File.xls'));
    $response->headers->set('Content-Disposition', $d);
    return $response;
}

我上面的代码工作正常,但它是这样做的实际方法吗?使用 file_get_contents 获取文件是否很好?

谢谢你

4

2 回答 2

10

编辑 2013 年 3 月

大文件不应该遵循这个响应,游戏中有一个新玩家:https ://github.com/igorw/IgorwFileServeBundle

它支持 SendFile 将文件下载委托给 Apache/Ngnix,这要好得多。

编辑 2013 年 5 月

好消息:核心中现在提供了一个内置解决方案:BinaryFileResponse


旧回应:

有一个名为 Response 的新类StreamedResponse,它完全符合您的要求,但内存效率更高,并且由内核很好地处理。

StreamedResponse 表示流式 HTTP 响应。
StreamedResponse 对其内容使用回调。
回调应使用标准 PHP 函数(如 echo)将响应流式传输回客户端。如果需要,也可以使用 flush() 方法。

http://symfony.com/doc/master/components/http_foundation/introduction.html#streaming-a-response

所以对于一个大文件,你可以在没有 file_get_content 的情况下做到这一点:

<?php
use Symfony\Component\HttpFoundation\StreamedResponse;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;

$response = new StreamedResponse();
$response->setCallback(function () {
    $name = 'bigfile.pdf';
    $fp = fopen($name, 'rb');
    fpassthru($fp);
});
$d = $response->headers->makeDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, 'foo.pdf');
$response->headers->set('Content-Disposition', $d);
$response->send();
于 2012-08-21T14:36:15.423 回答
0

我无法让 Damien 的解决方案在控制器中工作。

这是我要做的工作:

<?php
...
return new StreamedResponse(
  function () use ($file) {
    readfile($file);
  }, 200, array(
            'Content-Type' => 'image/png',
            'Content-Disposition' => 'inline; filename="filename.png"')
);

信用:http ://ailoo.net/2013/03/stream-a-file-with-streamedresponse-in-symfony/

于 2013-04-09T04:00:13.733 回答