ThinkPHP中cache()方法直接加在Db查询链上最省事,配置Redis后调用cache(true,3600)即可自动缓存,框架生成SQL哈希key;带参数查询天然支持多实例缓存,Redis失败时静默降级为file;需手动清理更新后的缓存以防脏数据。

cache() 方法直接加在查询链上最省事
ThinkPHP 的 Db 查询构建器原生支持缓存,不需要手动读写 Redis。只要配置好 Redis 驱动,直接在查询末尾加 cache() 就行:
$data = Db::name('user')->where('status', 1)->cache(true, 3600)->select();
这个 true 表示启用缓存,3600 是秒级过期时间。框架会自动生成一个基于 SQL 语句哈希的 key(如 think_sql_7a8b9c...),自动存取。
- 不传第二个参数时,用 config/cache.php 中
stores.redis.expire的默认值 - 若想指定 key 名(比如后续要主动清除),可写成
cache('user_list_v2', 3600) - 注意:带参数的查询(如
where('id', $id))每次生成的 key 不同,天然支持多实例缓存
Redis 连接失败时 cache() 会静默降级为 file 缓存
尤其在 ThinkPHP 8.0+ 中,如果 config/cache.php 里 Redis 配置缺字段(比如漏了 database 或 host 为空)、或 Redis 服务未运行,cache() 不会报错,而是悄悄 fallback 到 file 驱动——你看到“缓存生效”了,其实压根没走 Redis。
立即学习“PHP免费学习笔记(深入)”;
- 必须显式填全
host、port、database、password(或 ACL 模式下的auth) - 检查日志:搜索
RedisException或Connection refused,首次连接失败会被记录 - 验证是否真走 Redis:用
redis-cli monitor看是否有SET/GET命令发出
手动 Cache::get/set 更适合复杂场景
当查询逻辑动态拼接、或需要复用已有 key(比如和前端请求参数强绑定)、或需判断缓存存在性再查库时,绕过 cache() 直接操作缓存更可控:
$key = 'user_profile_' . $uid;<br>$data = Cache::get($key);<br>if (false === $data) {<br> $data = Db::name('user')->find($uid);<br> Cache::set($key, $data, 3600);<br>}
-
Cache::get()返回false表示未命中(不是null),注意用全等判断 - 避免在高并发下击穿:可加锁或使用
Cache::remember()(TP6+)简化写法 - 若用
Cache::store('redis')显式指定驱动,确保 store 名和 config 中定义一致
缓存失效策略比设置更重要
缓存不是设了就完事。数据库更新后,对应缓存不清理,就会返回脏数据。ThinkPHP 没有自动失效机制,得自己处理:
- 写操作后立刻删缓存:
Cache::delete('user_list_v2')或Cache::tag('user')->clear()(需开启标签支持) - 慎用永久缓存(
expire => 0):TP8 默认timeout => 0会导致 Redis 连接永不超时,但业务数据必须有过期边界 - 高频更新表(如计数器)不适合整条缓存,考虑只缓存计算结果或改用 Redis 原生命令(
INCR)
真正卡住性能的往往不是缓存怎么设,而是缓存什么时候该扔掉——这点最容易被忽略。



















