75142913在线留言
【Laravel实战】保姆级配置Intervention 图片缓存插件_PHP技术_网络人

【Laravel实战】保姆级配置Intervention 图片缓存插件

Kwok 发表于:2022-04-24 11:24:53 点击:68 评论: 0

研究了2天,踩了很多坑,终于搞清楚怎么使用Intervention提供的图片缓存功能。网上的教程模棱两可,说得不清不楚的,包括官方文档都解释得很模糊,里面的坑不少,希望通过我下面的教程助你能完美配置成功。

一、实现效果

Intervention 是一个强大的图片处理插件(扩展),其主要功能由 Intervention Image 提供,包括了 裁剪、旋转、灰度、压缩等,官方文档了解更多:https://image.intervention.io/v2

在这里我们要使用的是 Intervention imagecache 专门为Laravel设计(依赖Illuminate/Cache包)图片缓存插件,可以通过URL参数返回图片大小:

https://meishiq.com/1.jpg //原始地址
http://meishiq.com/original/1.jpg //通过Intervention返回的原始地址
https://meishiq.com/resize/small/1.jpg //返回 120x90 大小的图片
https://meishiq.com/resize/medium/1.jpg //返回 240x180 大小的图片
https://meishiq.com/resize/large/1.jpg //返回 480x360 大小的图片

上面地址实现是不存在的,这里只是demo URL。

imagecache 解决了传输原图以浪费服务器资源与带宽的问题,功能强大。下面开始准备安装体验。

二、Interventio/image与Interventio/imagecache安装

1、通过 composer 安装:

 php composer.phar require intervention/image
 php composer.phar require intervention/imagecache

关于与非laravel的使用请参考官方文档,这里只针对Laravel的安装使用。

2、配置 Laravel 

打开config/app.php 文件,找到$providers数组,在里面增加项:

InterventionImageImageServiceProvider::class,

然后在下面的 $aliases数组里增加:

 'Image' => InterventionImageFacadesImage::class

最后通过 artisan 命令发布Intervention Image:

php artisan vendor:publish --provider="InterventionImageImageServiceProviderLaravelRecent"

运行上面的命令后会将配置文件复制到config/image.php(只有1个配置项)、config/imagecache.php(主要配置这个文件)。

三、配置图片缓存

请仔细阅读此步骤,虽然只有4个项目可配置,但这是踩坑最多的地方,理解了配置文件对于后期使用的帮助很大。

1、配置文件项:

'route' => 'resize',//路由注入

 配置此项后,缓存路由就绑定在了/resize/* 下面,路由分为3个部分,即:{route}/{template}/{filename},现在我们完成了route配置,其resize可以根据自己喜好命名。

第二项 template 可以保持默认即可,现在我们需要测试一下配置是否成功,请使用下面的命令:

 php artisan route:list 

返回下面的内容:

resize/{template}/{filename} ................. imagecache › InterventionImage › ImageCacheController@getResponse

说明路由绑定成功了,那么输入这个路由,所访问的资源是在什么地方呢?这是坑1开始。

2、资源读取路径

继续向下看此配置项:

'paths' => [
    public_path('upload'),
    public_path('images')
],

要完全理解此项,我们必须先了解Laravel辅助函数public_path(),此函数返回我们public目录的路由,我们通过:

echo public_path();//var/www/html/public/

输出我本机的绝对URI。如果是新建项目的情况下,此目录只有一个index.php公开的入口文件,我们所上传的图片资源一般在:storage/app/public 目录,这里填坑软链接:

php artisan storage:link

此命令会在public目录下生成一个快捷方式,并连接到:storage/app/public 目录,现在我们可以通过路由 /storage/* 方式访问到 storage/app/public 目录下的资源。如果要自定义 storage,只需要重命令此文件即可(我改为了 images)。

现在我需要 访问 storage/app/public/caipu/100/100001/cover_0c7806a5f7c93bae.jpg 下的小图版,配置如下:

'paths' => [
    public_path('images/caipu'), //真实路径:storage/app/public/caipu(软链接后)
    public_path('images')
],

通过下面的路由尝试访问小图:

/images/caipu/100/100001/cover_0c7806a5f7c93bae.jpg //软链接后的原始地址
/resize/original/caipu/100/100001/cover_0c7806a5f7c93bae.jpg //通imagecache的原始地址
/resize/small/caipu/100/100001/cover_0c7806a5f7c93bae.jpg //裁剪后的small图片
/resize/medium/caipu/100/100001/cover_0c7806a5f7c93bae.jpg //裁剪后的medium图片
/resize/large/caipu/100/100001/cover_0c7806a5f7c93bae.jpg //裁剪后的large图片

OK,我们的配置完成了,如果按照上面的配置走一次,基本上是OK的。注意要软链接软链接软链接!!!然后在paths里配置软连接对的公开URL。

如果上面的3种大小无法满足的情况,可以查看官方文档,自建一个过滤器,配置自己所需要的图片大小。

3、image 缓存时间

'lifetime' => 43200//43200分钟(30天)

在缓存有效期内,所有的GD图片操作都会绕过,并直接返回可用的缓存图像,你可根据自己需要调整时间。

注意:使用 original 查看原始图片时使用的 file_get_contents 函数,会先读取到内存,然后再返回给http服务器,所以会消耗服务器资源。此方式不适合读取一些大型图片操作,会导致PHP超过默认使用的内存。

四、关于图片缓存相关

1、缓存文件存放路径

Intervention 调用的是Laravel的缓存系统,当使用file做为缓存的驱动时,会在storage/framework/cache/data 生成缓存二进制文件,内容如下:

1653370022s:41146:"ÿØÿà^@^PJFIF^@^A^A^A^@`^@`^@^@ÿþ^@;CREATOR: gd-jpeg v1.0 (using IJG JPEG v80), quality = 90

我遇到的坑为:使用了database做为缓存,但在mysql里,cache表里看不到缓存的信息,而文件里也不生成缓存文件,尝试查看问题,打开:vendor/laravel/framework/src/Illuminate/Cache/DatabaseStore.php 文件,在 function put()方法里看到下面代码:

try {
    return $this->table()->insert(compact('key', 'value', 'expiration'));
} catch (Exception $e) {
    $result = $this->table()->where('key', $key)->update(compact('value', 'expiration'));
    dd('缓存失败' . $e);//我增加的代码
    return $result > 0;
}

报错信息如下:SQLSTATE[HY000]: General error: 1366 Incorrect string value: 'xFFxD8xFFxE0x00x10...' for column 'value' at row 1

说明并未缓存成功,图片是二进制数据数据,所以我尝试将cache表里的value字段修改为blob,然后刷新,缓存成功了!

2、清理图片缓存

使用命令可以清除所有的缓存:

php artisan cache:clear

3、目前图片缓存最优解决方案

上面尝试使用database缓存失败后,还是觉得直接以文件的形势保存到硬盘上比较保险,但会影响磁盘IO,所以,还是祭出杀手锏吧,将内存做为磁盘,让缓存存在于内存中(linux),配置方法参考: 

mount -t tmpfs -o size=1024m tmpfs storage/framework/cache

当然,更推荐使用专业的Redis缓存方式。不需要这么麻烦的配置!

在配置文件里强制使用文件缓存,增加以下配置项即可:

    'cache_driver' => 'file', //强制使用缓存类型

五、配合Nginx使用时遇到的404问题

最近上线项目后,发现通过Nginx的图片可以正常显示。但状态码全部都返回了 404 ,检查了各项设置,发现是缓存的问题,所以我们需要将缓存路由排除在外,我的路由名为: resize 所以我的nginx配置里使用了下面的代码:

# 排除缓存图片,以防止返回404状态码
location ~* ^/(?!resize).*.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc|webp|woff|woff2|js|css)$ {
    expires max;
    access_log off;
    add_header Cache-Control "public";
}
除非注明,网络人的文章均为原创,转载请以链接形式标明本文地址:https://www.55mx.com/post/216
标签:图片缓存laravel实战Kwok最后编辑于:2022-05-25 15:25:34
1
感谢打赏!

《【Laravel实战】保姆级配置Intervention 图片缓存插件》的网友评论(0)

本站推荐阅读

热门点击文章