缓存驱动配置错误导致Cache::get()返回null:driver名须与类名严格一致;Redis需检查host/port连通性及启用pconnect;File驱动注意runtime目录权限;Memcached key需合规且避免超长;序列化方式不统一引发取值乱码。

缓存驱动配置写错导致 Cache::get() 总是返回 null
ThinkPHP 的缓存初始化依赖 cache.driver 配置值与对应驱动类的严格匹配。常见错误是写成 redis(小写)但实际驱动类名为 Redis,或漏掉 memcached 的 d 拼错为 memcache——后者会静默 fallback 到 File 驱动,不报错但数据不走 Memcached。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
-
cache.driver必须与think\cache\driver\下的类名完全一致:File、Redis、Memcached - Redis 驱动需确保
redis.host和redis.port可连通,否则Cache::get()会直接返回null,而非抛异常 - Memcached 驱动要求 PHP 启用
memcached扩展(不是memcache),且memcached.host默认是127.0.0.1,非localhost(DNS 解析失败时会卡住)
Redis 连接池没配,高并发下 Connection refused
ThinkPHP 默认每个请求新建 Redis 连接,压测时容易触发 Connection refused 或 Too many open files。这不是代码问题,而是连接未复用。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 在
cache.php中启用pconnect:'redis' => ['pconnect' => true],让连接保持长链 - 确认 Redis 服务端
maxclients设置足够(默认 10000,但 PHP-FPM 子进程数 × 每个子进程连接数不能超限) - 避免在循环里反复调用
Cache::store('redis')->get(),应改用Cache::store('redis')->pull()批量读,减少命令往返
File 缓存路径权限不对,mkdir(): Permission denied
File 驱动本质是写文件,但 ThinkPHP 默认缓存目录为 runtime/cache/,若部署时该目录属主不是 Web 服务器用户(如 www-data),就会在首次写缓存时爆出 mkdir(): Permission denied。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 手动执行
chown -R www-data:www-data runtime/(根据实际 Web 用户调整) - 不要把
cache.path改成/tmp等系统目录——ThinkPHP 会在其下再建子目录,而/tmp的 sticky bit 可能导致子目录权限异常 - 上线前跑一次
php think cache:clear,它会强制触发目录创建和权限校验,比等用户访问时报错更早暴露问题
Memcached key 超长或含非法字符,add() failed
Memcached 协议限制 key 最长 250 字节,且只允许字母、数字、下划线和减号。ThinkPHP 默认用 md5($key) 做 key 规范化,但若手动传入的 key 是 URL 或 JSON 字符串,仍可能含空格、斜杠等,导致 add() failed 并静默失败。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 统一用
Cache::tag()+ 短标识符代替长 key,例如Cache::tag('user')->set('1001', $data),底层自动拼接命名空间,规避 key 长度风险 - 禁用原始 key 直接传入:避免
Cache::store('memcached')->get("user:{$id}:profile"),改用Cache::get("user_{$id}_profile") - Memcached 不支持过期时间设为 0(永不过期),ThinkPHP 会转成 30 天;若真要永不过期,得显式传
0并确保驱动版本 ≥ 6.0.8,否则被忽略
不同缓存驱动的序列化方式不兼容——比如 Redis 默认用 serialize(),File 驱动却可能用 json_encode()(取决于 cache.serialize 配置)。混用时看似存进去了,取出来却是乱码或 false,这种问题往往要查到序列化层才定位得到。



















