Symfony BinaryFileResponse是否切断文件的结尾?

Symfony BinaryFileResponse是否切断文件的结尾?,symfony,symfony-http-foundation,Symfony,Symfony Http Foundation,我有一个ZIP文件要通过Symfony提供。控制器如下所示: $headers = [ 'Content-Type' => 'application/zip', 'Content-Disposition' => 'attachment; filename="archive.zip"' ]; return new Response(file_get_contents($pathToFile), 201, $headers); 这个很好用。但是,如果我尝试使用Binar

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

$headers = [
    'Content-Type' => 'application/zip',
    'Content-Disposition' => 'attachment; filename="archive.zip"'
];
return new Response(file_get_contents($pathToFile), 201, $headers);
这个很好用。但是,如果我尝试使用BinaryFileResponse(作为备份),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
  • PHP7.0.8
  • Ubuntu 16.04
  • nginx1.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;
编辑2: 我发现了一件更有趣的事情:使用标准响应(工作代码)提供这个ZIP文件会创建一个可打开的文件,但是在其上运行
ZIP-T
会给出:

在zipfile的开头或内部增加1个字节

测试原始文件提供:


文件大小小于1MB。

因为我看到您返回了201个http头,所以我假设文件是使用相同的请求创建的。根据symfony文件:

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

解决方案: 当我在文本编辑器中打开生成的ZIP文件时,我发现在它的边缘有一个额外的空行

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


不知道这个换行符是从哪里来的,不过…

只是一个小提示,201响应是“已创建”状态,通常不应该返回响应体(在您的情况下是二进制响应)。看看:我试过了,但没有效果。事实上,文件发送时并没有任何内容,但只是文件的结尾被截断了。这里也一样:这个修复程序对我有效!非常感谢。奇怪的错误:PHP或Symfony在文件的开头添加了一个单独的空行(在我的例子中是JPG而不是ZIP)。无论我使用什么方法生成文件(最终生成的是BinaryFileResponse),这都是正确的。假设Symfony的某个地方有一只虫子?这是在Symfony2.8.15、Ubuntu 16.04、Apache2、PHP5.6上实现的。在Symfony 2.3中不是问题。我喜欢以bug的形式提交,但不确定我是否能够足够准确地跟踪它。如果遇到这种情况,请在