cache::clear()对thinkphp模型查询缓存无效,因其缓存键仅含类名、方法名和sql模板,不包含条件值且未打标;需改用db手动缓存、缓存标签或禁用模型缓存。

直接清模型缓存没用,因为 ThinkPHP 的模型查询缓存默认不带参数、不打标、不区分条件——你改了数据,但缓存键还是那个,Cache::clear() 也找不到它。
模型查询缓存为什么 Cache::clear() 不生效
模型调用 select() 或 find() 时,如果用了 cache(true) 或全局开启了查询缓存,框架会用类名 + 方法名 + SQL 模板生成缓存键,比如 user_select_123456。这个键不包含 where 条件值,也不进缓存标签系统。
-
Cache::clear('user')这种按标签清无效,因为模型缓存根本没打标 -
Cache::clear()全局清只清驱动级缓存(如runtime/cache/),但模型缓存可能已写入 Redis 且 key 名不匹配前缀 - Redis 驱动下若配置了
'prefix' => 'think_',而模型缓存 key 是user_select_...,那clear()根本扫不到
正确清除模型查询缓存的三种方式
必须绕过模型自带缓存机制,手动控制缓存生命周期。
- 改用
Db::name('user')->where(...)->cache('user_list_status_1', 3600)->select():显式传入带业务语义的缓存键,清的时候直接Cache::delete('user_list_status_1') - 用缓存标签 + 手动序列化:
$key = 'user_'.$status; Cache::tag('user')->set($key, $result->toArray(), 3600),之后用Cache::tag('user')->clear()一次性清所有用户相关查询 - 彻底禁用模型查询缓存:在模型里重写
getCacheKey()返回null,或统一在查询链末尾加->cache(false)
字段结构缓存和模板缓存是两回事,别混着清
很多人执行 php think clear 后发现模型查的还是旧字段,或页面没变,其实是清错了地方。
- 字段结构缓存存在
runtime/schema/或runtime/temp/下,删完要再跑一次\think\facade\Db::clearCache()才真正刷新 - 模板缓存路径是
runtime/view/,php think clear默认不碰它,得手动rm -rf runtime/view/ - HTML 静态缓存路径是
runtime/html/,也要单独处理,否则改了模板也看不到效果
权限缓存和计算字段缓存必须主动失效
Auth 规则、计算字段(如 total_price)这类强依赖数据库变更的缓存,不能靠定时过期,必须在数据写入后立刻清理。
- 改
auth_rule表后,必须调用Cache::clear('auth_rule')(TP6)或Cache::rm('auth_rule')(TP5.1+) - 商品价格变动时,除了清自身缓存,还得用
Cache::tag('calc_'.$id)->clear()清掉订单页、购物车等所有依赖该商品的计算缓存 - 注意事务顺序:一定要在
$model->save()成功提交后,再触发缓存清除,否则监听器读到的是旧快照
最常被忽略的是缓存键的稳定性——用 md5(json_encode($query->getOptions())) 生成键看似通用,但一旦查询选项里有 Closure、Resource 或动态时间戳,就会导致键不一致、命中率归零。业务场景明确时,优先用语义化键名,比如 user_status_active_page_2。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











