Ich benutze Laravel Storage und ich möchte Benutzer einige (größere als Speicherlimit) Dateien dienen. Mein Code wurde von einem post in SO inspiriert und es geht so:Download von Laravel Speicher ohne Laden der gesamten Datei im Speicher
$fs = Storage::getDriver();
$stream = $fs->readStream($file->path);
return response()->stream(
function() use($stream) {
fpassthru($stream);
},
200,
[
'Content-Type' => $file->mime,
'Content-disposition' => 'attachment; filename="'.$file->original_name.'"',
]);
Unfourtunately, ich laufe in einen Fehler für große Dateien:
[2016-04-21 13:37:13] production.ERROR: exception 'Symfony\Component\Debug\Exception\FatalErrorException' with message 'Allowed memory size of 134217728 bytes exhausted (tried to allocate 201740288 bytes)' in /path/app/Http/Controllers/FileController.php:131
Stack trace:
#0 /path/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php(133): Symfony\Component\Debug\Exception\FatalErrorException->__construct()
#1 /path/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php(118): Illuminate\Foundation\Bootstrap\HandleExceptions->fatalExceptionFromError()
#2 /path/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php(0): Illuminate\Foundation\Bootstrap\HandleExceptions->handleShutdown()
#3 /path/app/Http/Controllers/FileController.php(131): fpassthru()
#4 /path/vendor/symfony/http-foundation/StreamedResponse.php(95): App\Http\Controllers\FileController->App\Http\Controllers\{closure}()
#5 /path/vendor/symfony/http-foundation/StreamedResponse.php(95): call_user_func:{/path/vendor/symfony/http-foundation/StreamedResponse.php:95}()
#6 /path/vendor/symfony/http-foundation/Response.php(370): Symfony\Component\HttpFoundation\StreamedResponse->sendContent()
#7 /path/public/index.php(56): Symfony\Component\HttpFoundation\Response->send()
#8 /path/public/index.php(0): {main}()
#9 {main}
Es scheint, dass es versucht, alle die laden Datei in den Speicher. Ich hatte erwartet, dass die Verwendung von Stream und Passhru dies nicht tun würde ... Gibt es etwas in meinem Code fehlt? Muss ich irgendwie die Chunkgröße angeben oder was?
Die Versionen, die ich verwende, sind Laravel 5.1 und PHP 5.6.
Das einzige Szenario, das ich mir vorstellen kann, wo 'fpassthru' in den Speicher zuweist, ist, wenn die Ausgabepufferung verwendet wird. Sie können daher eine Schleife auf 'fread' mit einem' echo' versuchen. – bishop