还在为项目中缓存的管理而感到心累,操作DB后忘了清理缓存?缓存与DB不一致?等......话不多说先看思路
利用模型观察者Observer去监听模型更新、删除等操作,拿到当前操作模型,找出缓存key,删掉即可。原理很简单,下面看一下代码
先封装一个基础类
<?php
namespace App\Observers;
use Illuminate\Database\Eloquent\Model;
class Observer
{
// 可监听的操作 creating created updating updated saving saved deleting deleted restoring restored
/**
* 当前操作模型
*
* @var Model
*/
protected $model;
/**
* 获取所有的缓存key
*
* @return array
*/
protected function getCacheKeys(): array
{
return [];
}
/**
* 清理缓存
*
* @return int 删除数量
*/
protected function clearCache(): int
{
$keys = $this->getCacheKeys();
if ($keys === []) {
return 0;
}
$redis = redis();
$cacheKeys = [];
foreach ($keys as $key) {
// 如果是通配符,查一下所有的缓存key
if (strpos($key, '*')) {
$cacheKeys = array_merge($cacheKeys, $redis->keys($key));
} else {
$cacheKeys[] = $key;
}
}
// 去重并删除缓存
return $redis->del(array_unique($cacheKeys));
}
}
定义一个GoodsSpu模型的观察者类GoodsSpuObserver.php 重点是getCacheKeys
这个函数,配置好返回需要清理的缓存key,每个模型配置这个函数即可
<?php
namespace App\Observers;
use App\Common\RedisKey;
use App\Models\GoodsSpu;
class GoodsSpuObserver extends Observer
{
public function saving(GoodsSpu $goodsSpu)
{
$this->model = $goodsSpu;
parent::clearCache();
}
public function deleted(GoodsSpu $goodsSpu)
{
$this->model = $goodsSpu;
parent::clearCache();
}
protected function getCacheKeys(): array
{
return [
// 商品详情key
sprintf(RedisKey::GOODS_DETAIL, $this->model->getAttribute('enterprise_id'), $this->model->getAttribute('id')),
];
}
}
接着注册一下GoodsSpuObserver
App\Providers\AppServiceProvider中加入
// SPU表观察者
GoodsSpu::observe(new GoodsSpuObserver());
测试一下更新记录的时候缓存是不是会自动被刷掉
// 简单的更新一下记录
$goodsSpu = GoodsSpu::query()->where('id', '=', 1)->first();
$goodsSpu->update([
'updated_at' => time()
]);
return 'success';
观察一下redis
结束