如何通过ThinkPHP空值缓存策略有效避免缓存穿透问题?
- 内容介绍
- 文章标签
- 相关推荐
本文共计687个文字,预计阅读时间需要3分钟。
ThinkPHP中,当使用默认查询无法查到数据时,返回`null`。而使用`Cache::get()`时,遇到`null`不会写入缓存——这等于是将缓存穿透放行。空值不能直接存入缓存,必须使用占位符++明确+TTL才有生效。
为什么 Cache::set('key', null, 300) 没用?
ThinkPHP 的 Redis 驱动在序列化时会跳过 null,或把它转成空字符串,实际没写进 Redis;更糟的是某些版本会把 null 当作永久缓存,导致后续真实数据再也刷不进去。
- 验证方法:用
redis-cli直接GET key,返回(nil)或空响应,说明根本没存成功 - file 驱动下写
null会生成非法文件名,静默失败,runtime/cache/里找不到对应文件 - 别依赖
Cache::remember()自动处理空值——它只在回调返回非空时才缓存
空值缓存的正确写法(TP6/7)
所有查询入口必须统一走“先查缓存 → 查不到再查 DB → 无论是否查到都写缓存”逻辑,且空结果必须用可识别的占位符。
本文共计687个文字,预计阅读时间需要3分钟。
ThinkPHP中,当使用默认查询无法查到数据时,返回`null`。而使用`Cache::get()`时,遇到`null`不会写入缓存——这等于是将缓存穿透放行。空值不能直接存入缓存,必须使用占位符++明确+TTL才有生效。
为什么 Cache::set('key', null, 300) 没用?
ThinkPHP 的 Redis 驱动在序列化时会跳过 null,或把它转成空字符串,实际没写进 Redis;更糟的是某些版本会把 null 当作永久缓存,导致后续真实数据再也刷不进去。
- 验证方法:用
redis-cli直接GET key,返回(nil)或空响应,说明根本没存成功 - file 驱动下写
null会生成非法文件名,静默失败,runtime/cache/里找不到对应文件 - 别依赖
Cache::remember()自动处理空值——它只在回调返回非空时才缓存
空值缓存的正确写法(TP6/7)
所有查询入口必须统一走“先查缓存 → 查不到再查 DB → 无论是否查到都写缓存”逻辑,且空结果必须用可识别的占位符。

