cache::set()返回true但get()为null,是tp8静默降级至file驱动所致;应先执行(new \think\cache\driver\redis(config('cache.stores.redis')))->handler()->ping()验证连接,返回+pong才表示redis真正连通。

Cache::set() 返回 true 但 get() 是 null,先验证 Redis 是否真连上了
这不是代码写错了,而是 TP8 的静默降级机制在起作用:连接失败时自动 fallback 到 file 驱动,不报错、不提示,只默默换底层。你看到 Cache::set() 返回 true,其实写的是本地文件,Cache::get() 当然拿不到 Redis 里的值。
最快验证方式是进命令行:
php think tinker
> (new \think\cache\driver\Redis(config('cache.stores.redis')))->handler()->ping()
必须返回 +PONG 才算通。返回 false、null 或抛出异常,说明配置或网络有问题——别往下调业务逻辑,先停在这步。
-
host必须是字符串(如'127.0.0.1'),不能留空或注释掉 -
port必须是整型(6379),写成'6379'会静默失败 -
database必须显式指定(如0),不填会导致部分命令(如SELECT)执行失败 - Redis ≥6.0 启用 ACL 时,用
auth而非password,且确认用户有+@all权限
config/cache.php 里漏了 persistent 或 timeout,高并发下写入会卡死或超时
TP8 默认不开启长连接,每次缓存操作都新建 TCP 连接。QPS 上去后,三次握手 + TIME_WAIT 就能吃掉大半性能,表现就是 Cache::set() 偶发性超时、慢、甚至失败。
timeout 字段也容易被忽略:它控制的是建立连接的超时时间(单位秒),不是 key 过期时间。设成 30(整型)不如设成 3.0(float),PHP 会更准确处理浮点超时。
- 务必加上
'persistent' => true,尤其在 FPM/Swoole 场景下 -
'timeout' => 3.0比3更稳妥,避免连接卡住阻塞整个请求 - 若 Redis 在 Docker 或远程服务器,建议加
'scheme' => 'tcp'显式声明协议 - 不推荐依赖
.env中的REDIS_HOST等变量——TP8 完全不读它们
session 和 cache 共用 database 导致 key 冲突,写入被覆盖或静默丢弃
TP8 的 cache 和 session 都直连 Redis,但默认都不加前缀:cache 存的是 think:xxx,session 存的是 PHPSESSID_xxx。看起来不重,但一旦你用了 Cache::tag()、自定义 store 或原生 $redis->set(),就极易撞上。
最稳妥的隔离方式不是靠 prefix,而是物理分库。因为 prefix 只是字符串拼接,而 database 是 Redis 内部的逻辑隔离空间,互不可见、互不影响。
- 在
config/cache.php中设'database' => 0 - 在
config/session.php的'store'数组里设'database' => 1 - 如果只能共用 database,两个地方都必须加
'prefix',且值不能相同(如'cache_'vs'sess_') - 别信“框架默认带 prefix”的说法——TP8 的 Redis store 默认
prefix是空字符串
Redis 写入失败报 “Error while writing bytes”,大概率是 maxmemory 触顶了
这个错误常被误判为网络或权限问题,实际八成是 Redis 自身内存满了。PHP 层面一切正常,ping 得通、set 返回 true,但数据就是不落地——因为 Redis 拒绝写入了。
查法很简单:
redis-cli CONFIG GET maxmemory redis-cli INFO memory | grep -E "used_memory|maxmemory"
如果 used_memory_human 接近或等于 maxmemory_human,且 maxmemory_policy 是 noeviction,那新写入就会直接失败。
- 临时解法:
redis-cli CONFIG SET maxmemory 0(慎用于生产) - 长期方案:调大
maxmemory,并选合适驱逐策略(如allkeys-lru) - 注意:PHP 的
memory_limit和 Redis 的maxmemory完全是两回事,别混淆 - ACL 用户没开
+set权限时,也会静默失败——用redis-cli AUTH测试是否能手动SET
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











