注解路由扫描不到的根源是topthink/think-annotation默认仅扫描app\controller命名空间,多应用如app\admin\controller需在config/annotation.php中显式配置'controllers'数组并包含对应命名空间路径,且须执行php think route:clear与route:cache刷新缓存。

注解路由扫描不到的根源是命名空间路径没配对
ThinkPHP 的 topthink/think-annotation 扩展默认只扫描 app\controller 命名空间下的类。你新建了 admin 应用,控制器实际在 app\admin\controller,但扩展根本不会主动“抬头看”这个目录——它连扫都不扫,自然找不到任何 #[Route]。
这不是语法错误,也不是 PHP 版本问题,而是扫描范围硬编码在配置里。哪怕你控制器里写了十遍 #[Route("admin/login")],只要没告诉扩展“去 app\admin\controller 里找”,它就当不存在。
- 检查
config/annotation.php中的'controllers'配置项,确认是否包含你的多应用控制器路径 - 路径必须是命名空间形式(如
app\admin\controller),不能写成文件路径(如app/admin/controller) - 多个应用需用数组列出:
['app\controller', 'app\admin\controller', 'app\api\controller'] - 改完配置后必须重新生成路由缓存:
php think route:cache,否则改动不生效
php think route:list 空列表?先确认注解路由是否真正启用
执行 php think route:list 结果为空,常见原因不是路由没写,而是注解解析根本没跑起来。最常漏掉的是两个开关:
-
config/app.php中'app_route' => true必须为布尔true(不是字符串或数字) -
config/route.php中'annotation' => true必须显式开启,否则即使装了扩展,框架也跳过注解解析 - 多应用下,子应用(如
app/admin/config/app.php)也要单独检查app_route开关,主应用配置不继承 - 执行命令时未加
--annotation参数(开发时常用),会导致扫描被跳过:php think build --annotation
#[Route] 写对了却还是 404?检查中间件和 URL 生成逻辑
注解路由注册成功 ≠ 能正常访问。很多 404 实际是中间件或 URL 构建环节断链:
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
立即学习“PHP免费学习笔记(深入)”;
-
app/middleware.php中必须注册think\middleware\ParseRule,否则注解路由规则不会被注入请求生命周期 -
url()函数默认不识别注解路由的路径字符串,比如#[Route("admin/login")]不能用url('admin/login')生成地址;必须配合#[Name("admin.login")],再调用url('admin.login') -
#[Name]的值必须全局唯一、小写字母+点号分隔,含空格或大写会直接失效 - PHP 8.5+ 下务必使用属性语法
#[Route],旧版文档块注释/** @Route */已不被支持
缓存机制让修改“看起来没反应”
ThinkPHP 注解路由在部署模式下会生成静态缓存文件(runtime/route/annotation.php),开发中改了注解却不生效,大概率是缓存没清干净:
- 改完
config/annotation.php或控制器注解后,必须运行:php think route:clear+php think route:cache - 如果只执行
route:cache而没先route:clear,旧缓存可能残留并覆盖新规则 - 某些 IDE 或 Docker 环境下,
runtime/目录权限不对,导致缓存写入失败但无报错,建议手动删掉runtime/route/整个目录再重试 - 调试阶段可临时把
app_debug设为true,强制每次请求都重新扫描注解(仅限开发环境)
最容易被忽略的是:多应用下每个子应用的 config/app.php 和 config/annotation.php 都要独立检查,而不是只动根目录那几份配置。


















