cache()是thinkphp 5最常用缓存写入函数,默认走file驱动,支持三种用法:传数组初始化配置、传两参数写入、传三参数指定有效期或null删除;常见失败原因包括目录权限不足、前缀覆盖、驱动扩展未启用及falsy值判断歧义。

cache() 是 ThinkPHP 5 中最直接、最常用的缓存写入函数,无需额外初始化即可使用(默认走 File 驱动),但实际行为受配置和参数影响较大。写错参数或忽略驱动限制,容易导致缓存不生效、路径错误甚至安全风险。
cache() 函数写缓存的三种典型用法
ThinkPHP 5 的 cache() 是多态函数:传不同参数类型,作用完全不同。
- 传数组 → 初始化缓存配置,例如
cache(['type' => 'redis', 'host' => '127.0.0.1']) - 传两个字符串/变量 → 写入缓存,
cache('key', 'value'),有效期用默认配置(DATA_CACHE_TIME或配置中expire) - 传三个参数 → 显式指定有效期,
cache('key', 'value', 3600),单位为秒;传null表示删除,cache('key', null)
注意:cache('key', 'value', 0) 不代表“永久”,而是按驱动默认策略处理(File 驱动下等同于不设过期,Redis 下可能被解释为立即过期,行为不一致)。
写入失败的常见原因和排查点
缓存“写了却读不到”,往往不是代码问题,而是环境或配置卡点。
-
runtime/cache/目录不存在或无写权限 → 检查CACHE_PATH是否可写,Linux 下常用chmod -R 755 runtime - 缓存前缀(
prefix)被意外覆盖 → 若在某处调用过cache(['prefix' => 'abc']),后续所有cache('key')实际写的是abc_key,但读时没带前缀就查不到 - 使用了
memcache或redis驱动但扩展未启用 →phpinfo()查memcached或redis模块是否加载,错误不会抛异常,只会静默退化为 file 缓存(如果配置允许) - 值为
false、null、空数组等“falsy”值 →Cache::get()返回false时无法区分是“缓存未命中”还是“缓存值就是 false”,建议统一用Cache::has('key')先判断存在性
文件缓存的实际落盘位置与结构
当使用默认 File 驱动时,缓存内容并非直写为 key.php,而是经哈希、压缩、加标签后写入:
- 真实路径由配置
path决定,默认是APP_PATH . 'runtime/cache/' - 若开启
cache_subdir(默认 true),会取 key 的 md5 前两位建子目录,如md5('user_123') === 'a1b2c3...'→ 落在runtime/cache/a1/b2c3... - 文件内容形如:
<?php exit(); $data = '...'; ?>(v5.0.15+ 补丁后强制exit(),防止 getshell) - 因此不能手动编辑这些文件来“伪造缓存”,反序列化或 gzip 解压逻辑由框架封装,直接改内容会导致
Cache::get()返回false
绕过 cache() 直接操作 Cache 类的场景
当需要更精细控制(比如带标签、跨存储、连接复用),应放弃 cache() 助手函数,改用门面类:
- 带标签写缓存:
Cache::tag('user')->set('profile_100', $data, 3600),之后可用Cache::clear('user')批量清空 - 临时切换驱动:
Cache::store('redis')->set('lock:order', 1, 10),避免全局配置污染 - 获取原生 handler:
$handler = Cache::init(['type'=>'file'])->handler(),用于调试或自定义写入逻辑
注意:所有通过 Cache:: 静态调用的操作,都依赖 think\facade\Cache 门面,它背后是容器自动解析的 think\Cache 实例 —— 这意味着你无法在非容器环境(如纯脚本 CLI)里直接 new 它,必须先启动框架或手动绑定。











