在heroku应用程序上下载文件时遇到问题。 我有一个基本的PHP语言,允许我们有128MB的内存限制。
我的错误如下:
(1/1)OutOfMemoryException错误:允许的内存大小为134217728 字节已耗尽(尝试分配77709312字节)
好的,我明白了,但是奇怪的是77709312bytes
只有74MB。
那怎么了? 这是我的下载操作的代码:
/**
* @Route("/templates/{id}/download", name="api_templates_download", requirements={"id"="\d+"})
* @Method({"GET"})
* @param \Symfony\Component\HttpFoundation\Request $request
* @return \Symfony\Component\HttpFoundation\Response
* @throws \Exception
*/
public function downloadTemplate(Request $request)
{
$id = $request->get('id');
try {
$template = $this->service->getTemplate($id, $this->helper->getUser());
$archive = $this->service->downloadTemplate($template);
$response = new Response(file_get_contents($archive));
$response->headers->set('Content-Type', 'application/zip');
$response->headers->set('Content-Disposition', 'attachment;filename="' . $archive . '"');
$response->headers->set('Content-length', filesize($archive));
return $response;
} catch (\Exception $e) {
$response = new Response(json_encode($e->getMessage()), 401);
$response->headers->set('Content-Type', 'application/json');
return $response;
}
}
然后在控制器中调用方法downloadTemplate
:
/**
* @tests Need to tests about performance - do this in september with real server
* @param \App\Domain\Dollycast\Template\Entity\Template $template
* @return string
*/
public function downloadTemplate(Template $template)
{
$zip = new \ZipArchive();
$zipName = self::ZIPDIR . $template->getName() . '.zip';
$zip->open($zipName, \ZipArchive::CREATE);
$finder = new Finder();
$finder->files()->in(self::WORKDIR . $template->getName());
$zip->addEmptyDir($template->getName());
/** @var SplFileInfo $file */
foreach ($finder as $file) {
// Rename the full path to the relative Path
$zip->addFile(
self::WORKDIR . $template->getName() . DIRECTORY_SEPARATOR . $file->getRelativePathname(),
$template->getName() . DIRECTORY_SEPARATOR . $file->getRelativePathname()
);
}
$zip->close();
return $zipName;
}
答案 0 :(得分:1)
(1/1)OutOfMemoryException错误:耗尽了134217728字节的允许的内存大小(试图分配77709312字节)
当时,php过程尝试分配已分配内存的77709312字节,可以使用memory_get_usage()函数进行检查。您的情况必须大于(134217728-77709312 =)56508416字节。
如果在创建zip文件的过程中引发了异常,则可以尝试使用外部工具来创建zip文件。像
exec(“ tar -zcvf archive.tar.gz / folder / tozip”);
否则,尝试找出引发此异常的确切时间,以尝试释放所有不必要的已用内存。
答案 1 :(得分:0)
file_get_contents
会将文件加载到内存中,当我将其放入Response
对象中时,这将有效地将所有内容从内存复制到输出缓冲区。这就是为什么74MB
附近的存档会由于双重工作而导致Out of memory
出现128M配置(74 * 2)错误的原因。
目前,我无法使用readfile()
来解决此问题,因为行为对于我的需求而言有太多不同。但是readfile()
将打开并输出到缓冲区,而无需使用两次内存。
编辑:我找到的最好的选择是通过使用Symfony 3.2的BinaryFileResponse
对象有效地处理响应流。
答案 2 :(得分:-1)
您尝试过file_get_contents($zipName); unlink($zipName);
以便从本地删除文件