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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 00:41:17  来源:igfitidea点击:

How should I serve an image with Laravel?

phpperformancelaravel

提问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 ImagesControllerclass

在你的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. enter image description here

它会显示你的形象,我已经自己制作并测试了它。 在此处输入图片说明

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/appthe $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.phpmodel:

在您的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