缓存生效关键在键名设计、驱动配置、失效同步三处细节:键名需含业务标识且规范前缀;必须启用Redis驱动并禁用隐式模型绑定;更新后须主动清理缓存,复杂查询推荐显式封装remember。

直接用 Cache::remember() 或 Eloquent 的 remember() 方法就能快速落地,但真正起效的关键不在“加缓存”,而在“键名设计、驱动配置、失效同步”这三处细节。
缓存键必须带业务标识,不能裸用 ID 或 URL
比如商品列表接口:GET /api/products?category=5&sort=price,若只用 products_list 作键名,所有分类、所有排序都会共用一个缓存,导致数据错乱。
- ✅ 正确写法:用参数组合生成确定性键名,如
"products:cat_{$category}:sort_{$sort}" - ⚠️ 避免用
request()->fullUrl()—— 参数顺序不同(?a=1&b=2vs?b=2&a=1)会生成不同 key,浪费缓存空间 - ⚠️ 不要省略前缀,比如
"user_1"容易和"users_1"冲突,建议统一加命名空间,如"api:users:show:{$id}"
Redis 驱动必须启用,且禁用隐式路由模型绑定
控制器方法写成 show(User $user) 看似方便,但 Laravel 会在进入 Cache::remember() 前就调用 User::find($id),数据库已查一次,缓存只是白套一层。
- ✅ 改为接收原始
$id,并在闭包内执行查询:Cache::remember("user:{$id}", 3600, fn() => User::find($id)) - ✅ 检查
.env中CACHE_DRIVER=redis是否生效,用php artisan tinker执行Cache::put('test', 'ok', 60)验证连通性 - ⚠️ 文件驱动(
file)不支持缓存标签,如果用了Cache::tags(['users'])->remember(...)却没切 Redis,会静默失败
模型更新后必须主动清理,不能依赖“自动失效”
Laravel 不监听原生 SQL 更新、队列任务或外部脚本的数据变更。只要不是通过 Eloquent 的 save()、update()、delete() 操作,缓存就不会自动清除。
- ✅ 在模型中注册观察者,
saved和deleted时手动Cache::forget("user:{$user->id}") - ✅ 批量更新(如
User::where(...)->update(['status' => 2]))不会触发模型事件,需额外补清理逻辑,例如Cache::tags(['users'])->flush() - ✅ 对于关联数据(如用户头像),更新
Avatar模型时,也要顺手清掉对应用户的缓存 key
复杂查询建议用 Cache::remember,别硬套 Eloquent remember()
User::with('posts')->remember(3600)->get() 看起来简洁,但它缓存的是整个集合对象,一旦中间有 dd()、toSql() 或闭包里漏了 use($status),缓存就完全失效,还不好排查。
- ✅ 推荐封装成独立方法,显式控制键名与逻辑:
Cache::remember("user_with_posts:{$id}", 3600, fn() => User::with('posts')->find($id)) - ✅ 返回值只缓存原始数组或集合,不要缓存
response()->json()或 Resource 实例,避免序列化失败 - ✅ 若需区分用户角色(如管理员看到全部,普通用户只看自己),键名必须包含角色标识:
"user_list:role_{$role}:dept_{$deptId}"


















