remember()缓存未生效主因是缓存驱动未启用、调试中断执行流、闭包变量未use、缓存键含非法字符;不可与Cache::remember()混用;失效需手动清理,键名必须唯一且带业务维度。

remember() 只缓存终端方法结果,不缓存查询构建过程;缓存键由实际 SQL + 参数值生成,不是模板;模型更新后不会自动失效,必须手动处理。
为什么 remember() 缓存没生效?
常见现象:加了 remember(3600) 但每次请求都走数据库,Redis 里查不到对应 key。
- 缓存驱动未启用或配置错误 —— 检查
CACHE_DRIVER=redis是否生效,运行php artisan tinker后执行Cache::put('test', 'ok', 60)确认连通性 - 用了
toSql()或dd()中断执行流 ——remember()是链式调用,一旦中间有调试语句打断,闭包不执行,自然不写缓存 - 闭包里引用了未
use的变量(如$request、$status)—— PHP 报错或返回空数组,缓存写入的是空值 - 缓存键含非法字符(如空格、斜杠)—— Laravel 会静默失败,建议用
md5()或sha1()哈希参数再拼接前缀
remember() 和 Cache::remember() 能混用吗?
不能。两者底层都是调用 Cache::remember(),重复包裹会导致逻辑混乱、键名冲突、TTL 不一致。
-
Post::where('status', 1)->remember(3600)->get()是标准用法,推荐 -
Cache::remember('posts_list', 3600, fn() => Post::where('status', 1)->get())是等效替代,适合需要自定义键名或跨模型组合的场景 - 同时写两层(比如在闭包里又调一次
->remember())—— 缓存值可能是空集合,且第二次缓存键无法命中 - 如果要用用户维度隔离(如不同角色看到不同列表),放弃
remember(),直接用Cache::remember("posts_{$role}_{$status}", ...)
缓存失效怎么保证不漏?
Laravel 不监听数据库直连、队列任务、外部脚本的数据变更,只响应模型自身的 saving/deleted 事件。
- 必须在模型中注册观察器或使用
static::saved等静态事件钩子,显式调用Cache::forget($key)或Cache::tags(['posts'])->flush() - 不要依赖默认键名 ——
remember(3600)生成的键是哈希值,调试时根本看不出来源;务必显式传参:remember(3600, 'posts_active_list') - 若用
Cache::tags(),确认驱动是redis或memcached;file驱动不支持标签,调用会静默失败 - 更新模型字段但未触发
saved(比如用update(['status' => 2])批量更新)—— 此时事件不触发,缓存也不会清,得额外补清理逻辑
最易被忽略的一点:缓存键是否真的唯一?相同业务逻辑在多个控制器里分别调用 remember(),但键名没区分上下文(比如都叫 posts_list),会导致 A 用户看到 B 用户的缓存结果。键名必须包含足以隔离的维度,哪怕只是加个版本号前缀。


















