thinkphp 6.x 不支持 config/cache.php 中的 default_expire 配置;缓存过期时间由驱动默认值(如 redis 默认3600秒)和方法调用时显式传参共同决定,且 cache::remember() 的过期时间必须作为第二个参数传入。

ThinkPHP 的 cache 配置里没有 default_expire 这个键
很多人在 config/cache.php 里加 'default_expire' => 3600,发现完全不生效——因为 ThinkPHP(6.x)压根不读这个配置项。全局缓存过期时间不是靠“统一配置”控制的,而是由驱动层默认值 + 方法调用时显式传参共同决定。
真正起作用的是各缓存驱动自身的 default_expire 属性,比如 FileCache 默认是 0(永不过期),RedisCache 默认是 3600。但这个默认值只在你调用 Cache::set($key, $value) 且**完全不传第三个参数**时才启用。
- 显式传了过期时间(如
Cache::set($key, $value, 600)),就以它为准 - 没传,才 fallback 到驱动内部的
$this->defaultExpire - 想改驱动默认值?得继承并重写对应驱动类,或在初始化时覆盖构造参数(不推荐)
用 Cache::remember() 时,过期时间必须每次指定
Cache::remember() 是最常被误用的地方:它看起来像“自动缓存”,但第二个参数才是过期时间,**不是第三个**。写成 Cache::remember('user_123', function () { return User::find(123); }, 3600) 是错的——第三个参数会被忽略,实际永远用默认值(通常是 3600 秒),和你写的 3600 毫无关系。
正确写法是把过期时间作为第二个参数:Cache::remember('user_123', 3600, function () { return User::find(123); })。漏掉它,或者放错位置,缓存就可能长期滞留或立刻失效。
- 常见错误现象:
Cache::remember('key', fn() => $data)→ 缓存永不刷新(因用了驱动默认 3600,但业务需要 60 秒) - 调试技巧:用
Cache::get('key', 'not found')查看是否真命中,别只信逻辑流程 - 注意闭包里抛异常会导致缓存写入失败,且不会 fallback 到数据库查询(除非你手动捕获)
不同缓存驱动对过期时间的处理差异很大
Redis 和 File 缓存看似都支持 TTL,但底层行为完全不同:Redis 的 EXPIRE 是原子操作、精确到秒;而 File 缓存靠文件修改时间 + 内存中预加载的过期检查,存在“缓存已过期但还没被清理”的窗口期,尤其在高并发下容易读到脏数据。
更隐蔽的问题是 Swoole 环境下的内存缓存(think-swoole 扩展启用时):SimpleCache 驱动用的是进程内数组,default_expire 完全无效——它根本不支持过期,只能靠手动 Cache::delete() 或重启 Worker 清理。
- Redis 驱动:支持毫秒级
setex,但 ThinkPHP 6.x 封装层仍只认秒级整数 - File 驱动:过期检查发生在
get()时,如果没人读,过期文件会一直占磁盘 - Apk/WinCache 等扩展驱动:部分不支持动态 TTL,设了也忽略,需查文档确认
想真正统一管理过期策略,得绕开 Cache Facade 直接封装
依赖框架默认行为去“全局控制过期时间”,本质是走不通的。靠谱做法是自己写一个轻量封装,比如 App\Service\CacheService,把常用业务场景的过期规则固化进去:
public function getUserCache(string $id): User
{
return Cache::remember("user:{$id}", 600, fn() => User::findOrFail($id));
}
public function getReportCache(string $type): array
{
return Cache::remember("report:{$type}", 1800, fn() => $this->buildReport($type));
}
这样既避免到处硬编码数字,又能在一处调整所有用户缓存的生命周期。比改配置文件、重写驱动、打补丁更可控,也更容易测试和交接。
记住:ThinkPHP 的缓存设计是“按需覆盖”,不是“集中管控”。越想一劳永逸地配个全局过期时间,越容易在某个深夜收到报警说缓存雪崩或者数据陈旧——因为那个“全局”根本不存在。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











