web-dev-qa-db-ja.com

Laravel 5ファイルのダウンロード:stream()またはdownload()

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ドキュメント にあります。

私の質問:どのような方法が望ましいか、それぞれの利点/欠点は何ですか?

私がこれまでに集めたものから:

ストリーム:

  • ファイル全体をメモリにロードする必要はありません
  • 大きなファイルに適しています

ダウンロード:

  • 必要なコードが少ない
15
Jones03

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 をご覧ください。

9
samrap