我应该如何用Laravel服务?

问题描述 投票:19回答:4

我将用户个人资料图片存储在laravel存储文件夹而不是公用文件夹中,因为我希望保持公共文件夹不干净,避免用户混乱。

为了从该文件夹提供图像,我创建了一个简单的Controller Action,如下所示:

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');
}

这可以被认为是一个好习惯,还是我应该只是将图片保存在公共文件夹中?这样做会遇到性能问题吗?

php performance laravel
4个回答
29
投票

您问题的简答

这可以被认为是一个好习惯,还是我应该只是将图片保存在公共文件夹中?这样做会遇到性能问题吗?

这不是建议的做法,因为你读取文件并重新生成它,这将花费处理时间并加载服务器,但这说明全部取决于请求数量,图像大小等。我使用这种做法来保护/保护来自公共访问的图像/文件,因此只有经过身份验证的成员才能访问此answer中的图像/文件。再次取决于文件大小,请求数量和服务器规格,我已经使用它一段时间,我没有性能问题,它工作正常(我的服务器是512MBMemory,1 CoreProcessor,20GBSSD磁盘VPS解决方案)。你可以尝试一下,看看。

符号链接解决方案

创建符号链接也是可能的

ln -s /pathof/laravel/storage/profile_pictures /pathof/laravel/public/profile

此解决方案不会影响性能,但您需要在内部文档中记录解决方案,以防您将设置移至新提供程序或需要重新链接到存储文件夹。

但是如果您仍然希望拥有从存储文件夹返回图像的完整解决方案,首先我们需要为Laravel安装Intervention Image,我不确定这是否已经完成。如果你已经安装它继续在这里,但如果不遵循这个答案的最后部分,而不是继续使用Laravel解决方案。

Laravel解决方案

如上所述,我们假设您的干预有效,首先您需要创建一个路线。 Route将转发所有图像请求访问我们的Controller。

创建路线

Route::get('profile/{person}', 'ImagesController@profilePicture');

创建路线后,我们需要创建一个控制器来处理来自路线的图像请求。

创建ImagesController

从命令

php artisan make:controller ImagesController

你的控制器看起来应该是这样的。

class ImagesController extends Controller {

    public function profilePicture($person, $size = 40)
    {
        $storagePath = storage_path('/profile_pictures/' . $person . '/profile_' . $size . '.jpg');

        return Image::make($storagePath)->response();
    }
}

并记得添加

use Intervention\Image\Facades\Image;

在你的ImagesController

最后确保您已使用测试图像创建了文件夹结构。

storage/profile_pictures/person/profile_40.jpg

现在,如果你在浏览器中写

http://laravelLocalhostUrl/profile/person

它会显示你的形象,我已经把它作为自己并测试它。 enter image description here

注意:我已尽力使文件夹反映您的问题,但您可以轻松修改它以符合您的需要。


安装干预(如果您已安装,请跳过此部分)

请遵循以下指南:http://image.intervention.io/getting_started/installation

简而言之:php composer require intervention/image

在你的config/app中,$ providers数组添加了这个包的服务提供者。

Intervention\Image\ImageServiceProvider::class

将此包的外观添加到$ aliases数组中。

'Image' => Intervention\Image\Facades\Image::class

解决方案的灵感来自这个answer,但一个是通过身份验证和这个answer来保护图像。


15
投票

使用Laravel 5.2+ Image::make($pathToFile)->response()可能被认为是不好的做法。任何寻找解决方案来提供Laravel图像的人都应该使用return response() -> file($pathToFile, $headers);。这将产生更少的开销,因为它只是提供文件而不是“在Photoshop中打开它” - 至少这是我的CPU显示器所说的。

这是link to documentation


3
投票

在你的User.php模型中:

protected $appends = ['avatar'];

public function getAvatarAttribute($size=null)
{
   return storage_path().'/profile_pictures/'.$this->id.'/profile_'.$size.'.jpg';
}

所以每当你打电话给一个用户实例时,你就会拥有他的化身。


0
投票
Response::stream(function() use($fileContent) {
    echo $fileContent;
}, 200, $headers);

https://github.com/laravel/framework/issues/2079#issuecomment-22590551

© www.soinside.com 2019 - 2024. All rights reserved.