Laravel 5文件下载:stream()或download()

Jon*_*s03 15 php download laravel laravel-5

我有一个Laravel 5.4应用程序,经过身份验证的用户需要能够从S3存储中下载私有文件.我已经设置了一个路由和控制器来允许私人文件下载.

代码如下所示:

路线:

Route::get('file/{filename}', 'FileController@download')->where(['filename' => '[A-Za-z0-9-._\/]+'])->name('file')->middleware('auth:employee');
Run Code Online (Sandbox Code Playgroud)

控制器:

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',
    ]);
}
Run Code Online (Sandbox Code Playgroud)

一切正常,但是当我仔细查看Laravel文档时,我发现他们只是谈论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),
    ]);
}
Run Code Online (Sandbox Code Playgroud)

这两个函数都可以在API文档中找到.

我的问题:什么是首选的方式,每个的优点/缺点是什么?

从我到目前为止收集的内容:

流:

  • 不需要将整个文件加载到内存中
  • 适合大文件

下载:

  • 需要更少的代码

sam*_*rap 9

当你给Laravel调用response()帮助器时,它会返回一个实例Illuminate\Routing\ResponseFactory.将ResponseFactory有以下两种方法:downloadstream-有问题的两种方法.如果你深入挖掘一下,你会看到download返回一个实例\Symfony\Component\HttpFoundation\BinaryFileResponse,而stream返回一个\Symfony\Component\HttpFoundation\StreamedResponse- 这些都是Symfony组件.

在这里挖掘代码是没有必要的,但是了解内幕发生的事情是很好的.现在我们知道返回的底层对象来自Symfony HTTP组件,我们可以参考Symfony文档并查看它们推荐使用的内容.通常,在文件大小未知时使用流,例如在动态生成文件时.在大多数其他情况下,该方法BinaryFileResponse生成的内容download足以满足您的需求.

您可以在此处查看有关HTTP Streaming及其用例的更深入的解释.