Symfony2 - 强制文件下载

2022-08-30 09:27:48

当用户单击下载链接时,我正在尝试下载文件。

在控制器中:

    $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(wihtout MVC)中做过,但我不知道通过Symfony2可以缺少什么...

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


答案 1

最舒适的解决方案是

use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;

$response = new BinaryFileResponse($file);
$response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT);

return $response;

答案 2

我最终在没有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;

推荐