Laravel 5.4アプリがあり、認証済みのユーザーはS3ストレージからプライベートファイルをダウンロードできる必要があります。プライベートファイルのダウンロードを許可するルートとコントローラーをセットアップしました。
コードは次のようになります。
ルート:
_Route::get('file/{filename}', 'FileController@download')->where(['filename' => '[A-Za-z0-9-._\/]+'])->name('file')->middleware('auth:employee');
_
コントローラ:
_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),
]);
}
_
両方の機能は APIドキュメント にあります。
私の質問:どのような方法が望ましいか、それぞれの利点/欠点は何ですか?
私がこれまでに集めたものから:
ストリーム:
ダウンロード:
Laravel the response()
]ヘルパーを呼び出すと、Illuminate\Routing\ResponseFactory
のインスタンスが返されます。ResponseFactory
には次の2つのメソッドがあります:download
およびstream
-問題の2つのメソッド少し深く掘り下げると、download
は\Symfony\Component\HttpFoundation\BinaryFileResponse
のインスタンスを返し、stream
は\Symfony\Component\HttpFoundation\StreamedResponse
-これらは両方ともSymfonyコンポーネントです。
ここでコードを掘り下げる必要はありませんが、内部で何が行われているかを理解しておくのは素晴らしいことです。返される基本オブジェクトがSymfony HTTPコンポーネントからのものであることがわかったので、Symfonyのドキュメントを参照して、使用が推奨されるものを確認できます。通常、ストリームは、ファイルをオンザフライで生成する場合など、ファイルのサイズが不明な場合に使用されます。他のほとんどの場合、BinaryFileResponse
メソッドによって生成されたdownload
で十分です。
HTTPストリーミングの詳細な説明とその使用例 here をご覧ください。