Laravel 9 的 remember() 方法是缓存数据库查询结果最直接的方式,它自动处理「查缓存 → 未命中 → 执行查询 → 写入缓存」全过程;支持 Eloquent 链式调用(如 User::where('status', 1)->remember(3600)->get())和 Cache 门面封装(如 Cache::remember('users_active_24h', 3600, fn() => User::where('last_seen', '>=', now()->subDay())->get())),二者本质相同但不可嵌套;缓存键必须唯一可预测、包含所有影响结果的参数(如分页、筛选、用户角色等),避免非法字符,需配合模型事件或手动调用 Cache::forget() 清理失效缓存,常见失效原因包括缓存驱动未启用、调试语句中断执行流、闭包变量未 use 及键名非法。

Laravel 9 的 remember() 方法是缓存数据库查询结果最直接的方式,它自动处理「查缓存 → 未命中 → 执行查询 → 写入缓存」全过程。用对了能明显降低数据库压力,用错了则可能完全不生效或缓存污染。
基础写法与关键细节
有两种常用调用形式,本质相同但适用场景略有区别:
-
Eloquent 链式调用:直接接在查询构造器后,适合简单模型查询
User::where('status', 1)->remember(3600)->get(); -
Cache 门面封装:更灵活,支持原生查询、多步逻辑、非 Eloquent 操作
Cache::remember('users_active_24h', 3600, fn() => User::where('last_seen', '>=', now()->subDay())->get());
注意:两种方式不能嵌套使用;闭包内必须 返回值(如 ->get() 或 ->first()),只调用不返回会导致缓存写入空值。
缓存键必须唯一且可预测
键名不是可有可无的装饰,而是缓存命中的核心依据。错误的键会导致不同请求互相覆盖,或永远无法命中。
- 避免裸用变量:
'users_list'这种静态键在多个控制器里重复使用,会混用数据 - 必须包含所有影响结果的参数:比如分页、筛选、排序、用户角色等
'products:cat_'.$category.'_page_'.$request->input('page').'_sort_'.$sort - 规避非法字符:URL 参数含空格、斜杠、中文时,建议先哈希或 URL 编码
'geo:addr_'.md5($address)
配合模型更新主动清理缓存
Laravel 不监听数据库直连或批量更新,缓存不会自动失效。必须在数据变更时手动清除:
- 在模型中注册观察器,在
saving/deleted等事件里调用Cache::forget($key) - 对批量操作(如
User::where(...)->update([...])),事件不触发,需额外补清理逻辑 - 使用标签(
Cache::tags(['users'])->put(...))可批量清除,但仅 Redis/Memcached 支持,file 驱动无效
常见失效原因排查
加了 remember(3600) 却每次走数据库?优先检查这几项:
- 缓存驱动是否启用:确认
.env中CACHE_DRIVER=redis生效,并用php artisan tinker手动测试连通性 - 调试语句中断执行流:在链式调用中插入
dd()、toSql()会跳过闭包,导致不写缓存 - 闭包变量未
use:例如引用了$request却没写function () use ($request),PHP 报错或返回空 - 键名含非法字符或为空:Laravel 会静默失败,不报错也不写入


















