Symfony BinaryFileResponse切断文件结尾?

时间:2016-09-27 06:38:27

标签: symfony symfony-http-foundation

我有一个通过Symfony提供的ZIP文件。控制器如下所示:

$headers = [
    'Content-Type' => 'application/zip',
    'Content-Disposition' => 'attachment; filename="archive.zip"'
];
return new Response(file_get_contents($pathToFile), 201, $headers);

这个很好用。但是,如果我尝试使用BinaryFileResponse(作为Documentation recommends),则ZIP文件会损坏:

$response = new BinaryFileResponse($pathToFile);
$response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT);
$response->setStatusCode(Response::HTTP_CREATED);
return $response;

尝试使用zip -FF archive.zip --out fixed.zip修复文件时得到的输出:

zip warning: End record (EOCDR) only 17 bytes - assume truncated

(此命令正确修复存档)

这是一个错误还是我做错了什么?

我的设置:

  • Symfony 2.8.11
  • PHP 7.0.8
  • Ubuntu 16.04
  • nginx 1.10.0

编辑:

我提出了改进建议,但问题仍然存在:

$response = new BinaryFileResponse($pathToFile);
$response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, 'archive.zip');
$response->headers->set('Content-Type', 'application/zip');
clearstatcache(false, $pathToFile);
return $response;

EDIT2:

我发现了一件有趣的事情:使用标准Response(工作代码)提供此ZIP文件会创建可打开的文件,但是在其上运行zip -T会给出:

  

在开头或在zipfile中的1个额外字节

测试原始文件给出:

  

文件大小小于1MB。

2 个答案:

答案 0 :(得分:2)

解:

当我在文本编辑器中打开生成的ZIP文件时,我发现了一个额外的空行...

所以我在返回Response对象之前添加了ob_clean();,现在它可以工作了!

不知道这个换行符来自哪里,但是......

答案 1 :(得分:0)

因为我看到你返回201 http头我假设文件已经创建了相同的请求。根据symfony文档:

  

如果您刚刚在同一个请求中创建了该文件,则该文件可能会在没有任何内容的情况下发送。这可能是由于缓存的文件统计信息为文件大小返回零。要解决此问题,请使用二进制文件的路径调用clearstatcache(false,$ file)。