Sto utilizzando Laravel Storage e voglio servire agli utenti alcuni file (più grandi del limite di memoria). Il mio codice è stato ispirato da un post in SO e va in questo modo:Download dalla memoria di Laravel senza caricare l'intero file nella memoria
$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, mi imbatto in un errore per file di grandi dimensioni:
[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}
sembra che tenta di caricare tutti i file in memoria. Mi aspettavo che l'uso di stream e passthru non lo farebbe ... C'è qualcosa che manca nel mio codice? Devo in qualche modo specificare la dimensione del blocco o cosa?
Le versioni che sto usando sono Laravel 5.1 e PHP 5.6.
L'unico scenario che posso pensare a dove 'fpassthru' alloca in memoria è quando si utilizza il buffering dell'output. Potresti quindi provare un ciclo su 'fread' con un' echo'. – bishop