Laravel 5 文件下载:stream() 或 download()
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/44965777/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Laravel 5 file downloads: stream() or download()
提问by Jones03
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.
我有一个 Laravel 5.4 应用程序,其中经过身份验证的用户需要能够从 S3 存储下载私人文件。我已经设置了一个路由和控制器来允许私人文件下载。
The code looks like this:
代码如下所示:
Route:
路线:
Route::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',
]);
}
All working fine, but when I had a closer look to the Laravel docs, I found that they just talk about response()->download()
.
一切正常,但是当我仔细查看Laravel 文档时,我发现他们只是谈论response()->download()
.
If I implement that kind of response, my code would look like this:
如果我实现这种响应,我的代码将如下所示:
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.
这两个函数都可以在API 文档中找到。
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
- Suitable for large files
- 不需要将整个文件加载到内存中
- 适用于大文件
Download:
下载:
- Requires less code
- 需要更少的代码
采纳答案by samrap
When you call Laravel the response()
helper, it returns an instance of the Illuminate\Routing\ResponseFactory
. The ResponseFactory
has these two methods: download
and stream
- the two methods in question. If you dig a little bit deeper, you'll see that download
returns an instance of \Symfony\Component\HttpFoundation\BinaryFileResponse
, while stream
returns a \Symfony\Component\HttpFoundation\StreamedResponse
- these are both Symfony components.
当您调用 Laravelresponse()
助手时,它会返回Illuminate\Routing\ResponseFactory
. 将ResponseFactory
有以下两种方法:download
和stream
-有问题的两种方法。如果你再深入一点,你会看到它download
返回一个 的实例\Symfony\Component\HttpFoundation\BinaryFileResponse
,而stream
返回一个\Symfony\Component\HttpFoundation\StreamedResponse
- 这些都是 Symfony 组件。
Digging through the code here isn't necessary, but it is nice to have an understanding of what's going on under the hood. Now that we know the underlying objects returned are from the Symfony HTTP Component, we can consult the Symfony docs and see what they recommend using. Typically, streams are used when the size of the file is unknown, such as when you are generating the file on the fly. In most other cases, the BinaryFileResponse
generated by the download
method will be sufficient for your needs.
没有必要在这里深入研究代码,但是了解幕后发生的事情是很好的。现在我们知道返回的底层对象来自 Symfony HTTP 组件,我们可以查阅 Symfony 文档并查看他们推荐使用的内容。通常,在文件大小未知时使用流,例如在动态生成文件时。在大多数其他情况下,该方法BinaryFileResponse
生成的download
将足以满足您的需求。
You can take a look at a much more in-depth explanation of HTTP Streaming and its use cases here.
您可以在此处查看对 HTTP 流及其用例的更深入的解释。