我有一个通过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
(此命令正确修复存档)
这是一个错误还是我做错了什么?
我提出了改进建议,但问题仍然存在:
$response = new BinaryFileResponse($pathToFile);
$response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, 'archive.zip');
$response->headers->set('Content-Type', 'application/zip');
clearstatcache(false, $pathToFile);
return $response;
我发现了一件有趣的事情:使用标准Response(工作代码)提供此ZIP文件会创建可打开的文件,但是在其上运行zip -T
会给出:
在开头或在zipfile中的1个额外字节
测试原始文件给出:
行
文件大小小于1MB。
答案 0 :(得分:2)
当我在文本编辑器中打开生成的ZIP文件时,我发现了一个额外的空行...
所以我在返回Response对象之前添加了ob_clean();
,现在它可以工作了!
不知道这个换行符来自哪里,但是......
答案 1 :(得分:0)
因为我看到你返回201 http头我假设文件已经创建了相同的请求。根据symfony文档:
如果您刚刚在同一个请求中创建了该文件,则该文件可能会在没有任何内容的情况下发送。这可能是由于缓存的文件统计信息为文件大小返回零。要解决此问题,请使用二进制文件的路径调用clearstatcache(false,$ file)。