php 我应该如何使用 Laravel 提供图像?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/36066144/
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
How should I serve an image with Laravel?
提问by clod986
I'm storing user profile pictures in laravel storage folder instead of the public folder because I would like to keep the public folder clean from user clutter.
我将用户个人资料图片存储在 Laravel 存储文件夹而不是公用文件夹中,因为我想让公用文件夹免受用户混乱的影响。
In order to serve an image from that folder, I created a simple Controller Action as follows:
为了提供该文件夹中的图像,我创建了一个简单的控制器操作,如下所示:
public function profilePicture($person, $size = 40){
$profile_picture_url = storage_path().'/profile_pictures/'.$person['id'].'/profile_'.$size.'.jpg';
if(!File::exists( $profile_picture_url ))
App::abort(404);
return Image::make($profile_picture_url)->response('jpg');
}
Can this be considered a good practice, or should I simply save pictures in the public folder? Will I run into performance issues by doing so?
这可以被认为是一个好习惯,还是我应该简单地将图片保存在公共文件夹中?这样做我会遇到性能问题吗?
回答by maytham-???????
The Short Answer to your Question
对您问题的简短回答
Can this be considered a good practice, or should I simply save pictures in the public folder? Will I run into performance issues by doing so?
这可以被认为是一个好习惯,还是我应该简单地将图片保存在公共文件夹中?这样做我会遇到性能问题吗?
It is not suggested practice, because you read the file and re-generate it, that will take process time and load the server, but that said all depends on how many requests, image size, etc. I used this practice to secure/protect images/files from public access, so only Authenticated member can access the images/files as it is in this answer. Again depending on file size, number of requests and server specification, I have used it for while and I have had no issues with performance, it has worked fine (my server is 512MBMemory, 1 CoreProcessor, 20GBSSD Disk VPS solution). You might give it a try for while and see.
这不是建议的做法,因为您读取文件并重新生成它,这将花费处理时间并加载服务器,但这一切都取决于请求的数量、图像大小等。我使用这种做法来保护/保护来自公共访问的图像/文件,因此只有经过身份验证的成员才能访问此答案中的图像/文件。再次取决于文件大小、请求数量和服务器规格,我已经使用它一段时间了,性能没有问题,它运行良好(我的服务器是 512MBMemory、1 个 CoreProcessor、20GBSSD Disk VPS 解决方案)。你可以试一试看看。
Symbolic link solution
符号链接解决方案
It is also possible, to create symbolic link like
也可以创建符号链接,如
ln -s /pathof/laravel/storage/profile_pictures /pathof/laravel/public/profile
This solution won't affect performance, but you need to document the solution in your internal documentation, in case you move your setup to new provider or in case you need to re-link to the storage folder.
此解决方案不会影响性能,但您需要在内部文档中记录该解决方案,以防您将设置移动到新的提供商或需要重新链接到存储文件夹。
But if you still wish to have the full solution for returning image from storage folder, first of all we need to install Intervention Image for Laravel, I am not sure if this done already or not. if you have install it continue here, but if not follow the last part of this answer and than continue with Laravel solution.
但是如果您仍然希望拥有从存储文件夹返回图像的完整解决方案,首先我们需要为 Laravel 安装干预图像,我不确定这是否已经完成。如果您安装了它,请在此处继续,但如果不遵循此答案的最后一部分,则继续使用 Laravel 解决方案。
Laravel solution
Laravel 解决方案
As said we assume your intervention works, first of all you need to create a Route. The Route will forward all image request access to our Controller.
如前所述,我们假设您的干预有效,首先您需要创建一条路线。Route 会将所有图像请求访问转发到我们的控制器。
Create Route
创建路线
Route::get('profile/{person}', 'ImagesController@profilePicture');
After creating a route, we need to create a controller to take care of image requests from our route.
创建路由后,我们需要创建一个控制器来处理来自路由的图像请求。
Create ImagesController
创建图像控制器
From command
从命令
php artisan make:controller ImagesController
And your controller should look like this.
你的控制器应该是这样的。
class ImagesController extends Controller {
public function profilePicture($person, $size = 40)
{
$storagePath = storage_path('/profile_pictures/' . $person . '/profile_' . $size . '.jpg');
return Image::make($storagePath)->response();
}
}
EDIT编辑
For those who use Laravel 5.2 and newer. Laravel introduces new and better way to serve filesthat has less overhead (This way does not regenerate the file as mentioned in the answer):
对于那些使用 Laravel 5.2 及更新版本的人。Laravel 引入了新的更好的方式来提供开销更少的文件(这种方式不会像答案中提到的那样重新生成文件):
File Responses
The file method can be used to display a file, such as an image or PDF, directly in the user's browser instead of initiating a download. This method accepts the path to the file as its first argument and an array of headers as its second argument:
return response()->file($pathToFile); return response()->file($pathToFile, $headers);
文件响应
file 方法可用于直接在用户浏览器中显示文件,例如图像或 PDF,而不是启动下载。这个方法接受文件的路径作为它的第一个参数和一个头数组作为它的第二个参数:
return response()->file($pathToFile); return response()->file($pathToFile, $headers);
And remember to add
并记得添加
use Intervention\Image\Facades\Image;
in your ImagesController
class
在你的ImagesController
班级
Finally be sure you have created folder structure with test image.
最后确保您已经使用测试图像创建了文件夹结构。
storage/profile_pictures/person/profile_40.jpg
Now if you write in your browser
现在如果你在浏览器中写
http://laravelLocalhostUrl/profile/person
It will show your image, I have made it my self and test it.
Note: I have tried best possible to make folder reflect your question, but you can easily modify it to fit the way you want.
注意:我已尽最大努力使文件夹反映您的问题,但您可以轻松修改它以适合您想要的方式。
Install Intervention(skip this part if you already installed it)
安装干预(如果已经安装,请跳过此部分)
Follow this guideline for it: http://image.intervention.io/getting_started/installation
请遵循以下指南:http: //image.intervention.io/getting_started/installation
Briefly: php composer require intervention/image
简要地: php composer require intervention/image
And In in your config/app
the $providers array add the service providers for this package.
并在您config/app
的 $providers 数组中添加此包的服务提供者。
Intervention\Image\ImageServiceProvider::class
Add the facade of this package to the $aliases array.
将此包的外观添加到 $aliases 数组中。
'Image' => Intervention\Image\Facades\Image::class
The solution inspired from this answerbut that one is to protect image with authentication in general and this answer.
回答by lukas83
Using Laravel 5.2+ Image::make($pathToFile)->response()
can be considered bad practise. Anyone looking for a solution to serve images from Laravel should use return response() -> file($pathToFile, $headers);
. This will produce much less overhead, as it just serves the file instead of "opening it in Photoshop" - at least that's what my CPU monitor says.
使用 Laravel 5.2+Image::make($pathToFile)->response()
可以被认为是不好的做法。任何寻找从 Laravel 提供图像的解决方案的人都应该使用return response() -> file($pathToFile, $headers);
. 这将产生更少的开销,因为它只是提供文件而不是“在 Photoshop 中打开它”——至少我的 CPU 监视器是这样说的。
Here's the link to documentation
回答by Jilson Thomas
In your User.php
model:
在您的User.php
模型中:
protected $appends = ['avatar'];
public function getAvatarAttribute($size=null)
{
return storage_path().'/profile_pictures/'.$this->id.'/profile_'.$size.'.jpg';
}
So whenever you call a get a User instance, you'll have his avatar along with it.
因此,无论何时您调用 get 一个 User 实例,您都会拥有他的头像。
回答by zhwei
Response::stream(function() use($fileContent) {
echo $fileContent;
}, 200, $headers);
https://github.com/laravel/framework/issues/2079#issuecomment-22590551
https://github.com/laravel/framework/issues/2079#issuecomment-22590551