thinkphp升级后路由缓存失效的根本原因是路由注册时机变更、动态路由未在缓存生成前执行、子域名路由隔离增强及多层缓存未彻底清除;需显式调用route::import()、手动清理runtime/route/、补全domain中间件与选项、禁用opcache并重启swoole进程。

路由缓存没更新,php think route:cache 之后还是走旧规则
升级 ThinkPHP(尤其是从 6.0.x 升到 6.1+ 或 6.2+)后,route:cache 命令看似执行成功,但请求仍匹配不到新定义的路由,甚至 404。根本原因不是命令没跑,而是缓存文件生成逻辑变了:新版默认把路由注册时机从「应用初始化前」挪到了「容器绑定后」,导致缓存生成时部分路由尚未注册。
实操建议:
- 检查
app/route.php是否只做了Route::get()这类静态注册 —— 新版要求必须显式调用Route::import()或确保路由文件被Route::rules()加载路径覆盖 - 确认
config/route.php中'build_cache' => true已开启,且'cache_key' => 'route_cache'没被意外覆盖 - 手动删掉
runtime/route/目录再重跑php think route:cache,避免旧缓存残留干扰判断 - 如果用了多应用模式,
route:cache默认只处理当前应用,需加--app=xxx参数指定
Route::rule() 定义的路由在缓存后不生效
很多老项目习惯用 Route::rule() 动态拼接路由,比如根据数据库配置生成后台菜单路由。这类路由在缓存机制下直接丢失 —— 因为 route:cache 只序列化静态 PHP 数组结构,不执行运行时代码。
实操建议:
- 把动态路由逻辑提前到
app/route.php文件顶层执行,确保在缓存生成阶段就完成注册(即:不要包在闭包、控制器方法或事件监听里) - 若必须动态加载,改用
Route::import()导入一个返回数组的 PHP 文件,该文件可含简单逻辑(如读取本地 JSON),但禁止涉及数据库、HTTP 请求等阻塞操作 - 验证是否生效:运行
php think route:list,看输出里有没有你的动态路由;没有,说明缓存阶段根本没注册进去
升级后 Route::domain() 子域名路由全挂了
ThinkPHP 6.1+ 对域名路由做了隔离增强,Route::domain() 注册的子路由不再自动继承父级中间件和参数解析规则,缓存后更明显:所有子域名请求都 fallback 到默认路由或直接 404。
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
实操建议:
- 每个
Route::domain()块内必须显式调用->middleware()和->option(),不能依赖全局配置 - 检查
config/route.php中'domain_bind' => []是否为空 —— 若启用了域名绑定,需确保键名与Route::domain()第一个参数完全一致(包括端口,如'admin.test:8080') - 缓存文件里会生成独立的 domain 路由树,用
var_dump(include runtime/route/cache.php)可看到结构变化,重点看'domain'键下是否有对应条目
php think route:clear 清不掉路由缓存
命令返回“Clear success”,但下次请求还是走缓存,甚至 route:cache 都报“Cache exists”。这不是命令失效,而是 ThinkPHP 的路由缓存分两层:一层是 runtime/route/ 下的 PHP 文件,另一层是 think\Container 内部的静态属性缓存(尤其在 Swoole 或 Hyperf 兼容模式下)。
实操建议:
- 先删物理文件:
rm -rf runtime/route/,别只信route:clear - 如果是 CLI 模式调试,加
-d opcache.enable=0参数防止 OPcache 缓存了旧的路由文件(常见于 Docker 环境) - 在 Swoole 环境中,必须重启 Worker 进程,
route:clear对已加载的内存缓存无效 - 检查
config/app.php中'debug' => true是否开启 —— 关闭 debug 时,部分缓存跳过校验逻辑,容易误判
最麻烦的是混合使用了自定义路由加载器 + 多级命名空间 + Swoole 热重载,这时候路由缓存的生命周期跟容器实例、进程生命周期搅在一起,得盯着 Container::get('route') 的实例状态来定位。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










