I have a Laravel 5.4 app where authenticated users need to be able to download private files from S3 storage. I've setup a route and controller to allow private file downloads.
代码如下所示:
路由:
路由::get('file/{filename}', 'FileController@download')->where(['filename' => '[A-Za-z0-9-._\/]+'])->name('file')->middleware('auth:employee');
Controller:
public function download($fileName)
{
if (!$fileName || !Storage::exists($fileName)) {
abort(404);
}
return response()->stream(function() use ($fileName) {
$stream = Storage::readStream($fileName);
fpassthru($stream);
if (is_resource($stream)) {
fclose($stream);
}
}, 200, [
'Cache-Control' => 'must-revalidate, post-check=0, pre-check=0',
'Content-Type' => Storage::mimeType($fileName),
'Content-Length' => Storage::size($fileName),
'Content-Disposition' => 'attachment; filename="' . basename($fileName) . '"',
'Pragma' => 'public',
]);
}
一切都很好,但当我仔细观察Laravel docs时,我发现他们只谈论response()->download()
.
如果我实现这种响应,我的代码将如下所示:
public function download($fileName)
{
if (!$fileName || !Storage::exists($fileName)) {
abort(404);
}
$file = Storage::get($fileName);
return response()->download($file, $fileName, [
'Content-Type' => Storage::mimeType($fileName),
]);
}
Both functions can be found in the API docs.
My question: what would be the preferred way to go and what are the advantages/disadvantages of each?
From what I've gathered so far:
Stream:
- Does not require the whole file to be loaded into memory
- 适用于大文件
Download:
- 需要更少的代码