thinkphp 8.0无一键全局关缓存开关,必须分类型处理:模型查询缓存需显式key+手动delete;php think clear --all不清理模型/模板/字段/标签缓存;模板缓存需-t参数,路由缓存依赖app_debug=false,配置缓存需php think config:cache且opcache需重载。

ThinkPHP 8.0 没有“一键全局关闭缓存”的开关,所谓“关闭缓存”必须按缓存类型逐项处理——模型查询缓存、模板编译缓存、路由缓存、配置缓存、字段结构缓存、标签缓存,各自独立生效、各自需要独立清理或禁用。
模型查询缓存根本不会自动开启,cache(true) 是高危写法
TP8.0 的模型查询(find()、select()、count() 等)默认完全不走缓存,哪怕你配置了 Redis 驱动。必须显式调用 cache() 才会写入/读取缓存。但直接写 cache(true) 极其危险:
-
cache(true)只对find(1)这类无参静态查询安全;其他场景(如带where()、order()、with())会因 SQL 片段微小差异导致缓存键冲突或完全不命中 - 关联查询(
with('profile'))和聚合函数(count())下cache()基本失效,因为缓存键只基于主表 SQL,忽略子查询上下文 - 软删除模型(
use SoftDelete)查出的可能是逻辑删除后的“脏数据”,缓存层无法感知delete_time字段变化
正确做法是:显式传入自定义 key + 过期时间,例如 UserModel::where('status', 1)->cache('user_active_list', 600)->select();增删改操作后,必须手动清理对应 key:Cache::delete('user_active_list')。
php think clear --all 清不掉模型查询缓存
执行 php think clear --all 后仍有旧数据?不是命令没执行成功,而是它压根不碰模型层缓存。该命令只清「驱动级缓存」——即 runtime/cache/ 下的文件、Redis 中带统一 prefix 的 key(如 think_:xxx),但以下几类完全遗漏:
- 模型查询缓存(
UserModel::cache('key')->select()生成的 key 不进标签系统,也不走默认 prefix) - 模板编译缓存(在
runtime/view/,必须加-t参数才清) - 字段结构缓存(存在
runtime/schema/或runtime/temp/,需手动调\think\facade\Db::clearCache()) - 自定义 store 实例(如
Cache::store('my_redis'),除非显式调用->clear())
验证是否真清了:别信返回值,直接 var_dump(file_exists(runtime_path() . 'cache/user_active_list.php'))(File 驱动)或 Redis 里 exists user_active_list(自定义 key 无 prefix 时)。
模板、路由、配置缓存各有一套清理逻辑,混着清等于白清
模板缓存关不掉?不是代码问题,是配置没对上:
- 模板编译缓存由
'template' => ['cache' => false]控制,但仅影响runtime/view/下的 PHP 编译文件;若已生成,需配合php think clear -t或删整个runtime/view/ - 路由缓存(
runtime/route.php)只在APP_DEBUG = false时生效;APP_DEBUG = true下无论是否执行php think route:cache都不启用——部署前务必确认config/app.php和.env中APP_DEBUG最终解析为false - 配置缓存(
runtime/config.php)同样依赖APP_DEBUG = false;修改config/app.php后,必须先php think config:cache,且确保runtime/目录可写;OPcache 还可能锁住旧配置,需重载 PHP-FPM
最稳妥的开发期绕过方式:入口文件 public/index.php 顶部加 define('THINK_ROUTE_CACHE', false),并设 'template' => ['cache' => false],再把缓存驱动临时切为 null。
缓存键生成机制本身就有缺陷,别迷信自动 key
TP 默认用 SQL 的 MD5 作缓存 key,看似唯一,实则脆弱:
- SQL 中拼接 PHP 变量(
"status = {$status}")会导致 key 随变量变,但缓存却不会自动失效 - 不同环境 SQL 格式差异(空格、换行)、数据库前缀不同,都会让 key 不一致,缓存形同虚设
- File 驱动在 Windows 下长 key(>255 字符)会静默失败;Redis 下
cache(0)表示永不过期,但 TP6.1+ 对 0 处理有 bug,建议传null或大数值(如31536000)
真正可靠的方案是:所有缓存都用语义化字符串 key(如 user_list_status_1),主动管理生命周期,而不是依赖框架自动生成的“黑盒 key”。模型增删改后,立刻 Cache::delete('user_list_status_1'),比等缓存自然过期更可控。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











