Cache::get()静默返回null主因是缓存未真正生效:store名与config/cache.php中default值不一致、Redis扩展未启用、或file驱动键名含非法字符导致写入失败。

Cache::get() 静默返回 null?不是代码错,是缓存根本没写进去,或写进去了但读不到——配错任意一层驱动、路径、store 名,都会这样。
config/cache.php 里 default 和 stores 必须对齐
TP6 不是“设了 type 就生效”,而是靠 default 值去 stores 里找对应键。常见错误:把 'default' => 'redis' 写了,但 stores 里只定义了 'redis_cache' 或拼成 'redsi',结果自动 fallback 到内置 file 驱动,而你根本没检查 runtime/cache/ 是否可写。
-
default必须和stores的数组键完全一致(大小写敏感) - 如果用
Cache::store('redis'),那stores['redis']这个键必须存在且完整 - 删掉没用的 store 配置项,避免干扰判断;开发时可临时把
default改成file快速验证逻辑是否走通
Redis 驱动必须装扩展且 PHP 要加载 redis 模块
TP6 默认不带 Redis 驱动,Driver [redis] not supported 或 Class 'Redis' not found 都指向同一问题:只跑了 composer require topthink/think-redis,但没确认 PHP 环境里 redis 扩展已启用。
- Linux/macOS 下执行
php -m | grep redis,有输出才表示扩展就位 - Docker 环境注意:PHP 容器里要单独安装
php-redis包(如docker-php-ext-install redis),不能只靠宿主机 - 配置中
'type' => 'redis'是小写;旧项目若写成'Redis'会报错
缓存键名含空格/中文/斜杠 → file 驱动静默失败
file 驱动把键名直接当文件名用。Cache::set('user/name', $data) 会在 runtime/cache/ 下尝试创建 user/name.php,但目录不存在就写不进,也不报错,get() 自然返回 null。
立即学习“PHP免费学习笔记(深入)”;
- 统一用
md5($key)或正则过滤:preg_replace('/[^a-zA-Z0-9_]/', '', $key) - Redis 驱动虽能存,但键名含特殊字符仍可能触发序列化异常或调试困难
- 哪怕只是开发阶段,也建议在封装层加一道校验:
if (!ctype_alnum(str_replace(['_', '-'], '', $key))) { throw new InvalidArgumentException('Invalid cache key'); }
Cache::remember() 失效常因闭包变量作用域漂移
Cache::remember('user_'.$id, 3600, function () use ($id) { return User::find($id); }) 看似稳妥,但若 $id 是从 request 获取、未显式 use,或闭包在循环里重复定义,TP6 生成的内部 key 就会变,导致“写一次,读不到第二次”。
- 永远显式
use所有外部变量,别依赖隐式捕获 - 避免在闭包里调用
$this->xxx或访问未声明的属性,这些会污染 key 生成逻辑 - 怀疑 key 不一致?用
redis-cli keys "think:cache:user*"直接查 Redis,看实际存了几个不同 key
最易被忽略的是:缓存键名合法性、store 名一致性、以及 PHP redis 扩展是否真在运行环境中加载——这三处出问题,不会抛异常,只会让缓存逻辑彻底静默失效。



















