'memory limit exhaused - symfony 5 with flysystem [duplicate]
I try to provide Download Streams for my Project, but always run into memory limit exhausted error on files larger than 128M.
php memory limit is set to 128M, and this should be ok on using streamed output.
I've tried the following
/**
* @param Upload $fileInfo
* @return StreamedResponse
* @throws FilesystemException
*/
public function getDownloadStream(Upload $fileInfo): StreamedResponse
{
try {
/** @var FilesystemOperator $storage */
$storage = $this->getStorageByFileInfo($fileInfo);
/** @var string $fileName */
$fileName = $fileInfo->getSystemFileName();
/** type is resource */
$stream = $storage->readStream($fileName);
$response = new StreamedResponse(function () use ($stream) {
fpassthru($stream);
flush();
});
$dispositionFileName = $this->getDownloadFileName($fileInfo);
$disposition = HeaderUtils::makeDisposition(
HeaderUtils::DISPOSITION_ATTACHMENT,
$dispositionFileName
);
$response->headers->set('Content-Transfer-Encoding', 'binary');
$response->headers->set('Content-Type', $fileInfo->getMimeType());
$response->headers->set('Content-Disposition', $disposition);
$response->headers->set('Content-Length', fstat($stream)['size']);
} catch (FilesystemException $e) {
$this->logger->log(LogLevel::ERROR, self::message_downloadFailed);
throw $e;
}
return $response;
}
Using a BinaryFileResponse
does not work because the files are located in different storage and not all are local.
And it looks like the StreamdResponse
loads fully into the memory before providing the files for download.
What do I have to change, expecting the memory_limit, to get it to work with large files?
EDIT: my solution is to use fwrite to write the content of the file chunk for chunk. It looks like fpassthru and session_copy_to_session, both put the full content for the stream to the memory.
...
$response = new StreamedResponse(function () use ($fileInfo) {
$outputStream = fopen('php://output', 'wb');
$fileStream = $this->readStreamByFileInfo($fileInfo);
while(!feof($fileStream)) {
fwrite($outputStream, fread($fileStream, 1024)); //write data from file into output in 1kb chunks
}
});
...
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|