如何配置ThinkPHP8.0的路由规则?
- 内容介绍
- 文章标签
- 相关推荐
本文共计871个文字,预计阅读时间需要4分钟。
TP8+ 的注释路径不是默认开启的功能。
漏掉任一环节,php think route:list 就看不到注解注册的路由,也不会报错——只会静默忽略。
- 检查
config/annotation.php是否存在,里面'route' => ['enable' => true]必须为 true - 控制器类必须位于
app/controller/(单应用)或按多应用结构匹配命名空间,例如appdmincontrollerIndex对应appdmincontroller - 方法必须是
public,否则注解解析器直接跳过
#[Get] 和 #[Route] 别混用,参数支持范围差别很大
#[Get("user/:id")] 是快捷写法,等价于 #[Route("user/:id", method="GET")],但仅此而已。它不支持中间件、域名、变量规则等关键配置。
如果你需要加权限控制或限定访问域,只能用 #[Route]:
立即学习“PHP免费学习笔记(深入)”;
#[Route("admin/:id", method="GET", middleware="auth", domain="admin.example.com", pattern: ["id" => "d+"])] public function detail($id) { // ... }
-
#[Get]/#[Post]适合简单接口,写起来快,但扩展性差 -
#[Route]才是完整能力入口,middleware、domain、pattern、name都只在这里生效 - 别在
#[Get]里硬塞middleware参数——会被完全忽略,连 warning 都没有
多应用下注解扫描不到?改 config/annotation.php 的 controllers 配置
默认情况下,topthink/think-annotation 只扫描 appcontroller 命名空间。你建了 appdmin 应用,它的控制器在 appdmincontroller,自然被跳过。
解决办法是显式补充扫描路径,在 config/annotation.php 中修改 'controllers' 配置项:
'route' => [ 'enable' => true, 'controllers' => [ 'app\controller', 'app\admin\controller', 'app\api\controller', ], ],
- 路径必须用双反斜杠转义,写成
appcontroller会解析失败 - 每个字符串代表一个命名空间前缀,对应一个目录,不要带末尾
controller子路径 - 改完后必须执行
php think clear:route,否则缓存仍用旧扫描结果
路由能访问但参数为空?检查变量规则和 method 匹配
比如写了 #[Route("user/:id")],访问 /user/123 却收不到 $id,常见原因有两个:
- 没指定
method,而当前请求是 POST,但注解默认只注册 GET 路由(#[Get]显式限定 GET,#[Route]不写method默认也是 GET) - 变量未定义规则,
:id允许任意字符,但框架内部可能因正则不匹配导致参数丢弃;建议加pattern:#[Route("user/:id", pattern: ["id" => "d+"])] - URL 中有大小写或特殊字符,而默认变量规则不兼容;可全局设置
config/route.php中的'param_convert' => false关闭自动类型转换
最稳妥的做法是:所有带变量的 #[Route] 都显式声明 method 和 pattern,不依赖默认行为。
本文共计871个文字,预计阅读时间需要4分钟。
TP8+ 的注释路径不是默认开启的功能。
漏掉任一环节,php think route:list 就看不到注解注册的路由,也不会报错——只会静默忽略。
- 检查
config/annotation.php是否存在,里面'route' => ['enable' => true]必须为 true - 控制器类必须位于
app/controller/(单应用)或按多应用结构匹配命名空间,例如appdmincontrollerIndex对应appdmincontroller - 方法必须是
public,否则注解解析器直接跳过
#[Get] 和 #[Route] 别混用,参数支持范围差别很大
#[Get("user/:id")] 是快捷写法,等价于 #[Route("user/:id", method="GET")],但仅此而已。它不支持中间件、域名、变量规则等关键配置。
如果你需要加权限控制或限定访问域,只能用 #[Route]:
立即学习“PHP免费学习笔记(深入)”;
#[Route("admin/:id", method="GET", middleware="auth", domain="admin.example.com", pattern: ["id" => "d+"])] public function detail($id) { // ... }
-
#[Get]/#[Post]适合简单接口,写起来快,但扩展性差 -
#[Route]才是完整能力入口,middleware、domain、pattern、name都只在这里生效 - 别在
#[Get]里硬塞middleware参数——会被完全忽略,连 warning 都没有
多应用下注解扫描不到?改 config/annotation.php 的 controllers 配置
默认情况下,topthink/think-annotation 只扫描 appcontroller 命名空间。你建了 appdmin 应用,它的控制器在 appdmincontroller,自然被跳过。
解决办法是显式补充扫描路径,在 config/annotation.php 中修改 'controllers' 配置项:
'route' => [ 'enable' => true, 'controllers' => [ 'app\controller', 'app\admin\controller', 'app\api\controller', ], ],
- 路径必须用双反斜杠转义,写成
appcontroller会解析失败 - 每个字符串代表一个命名空间前缀,对应一个目录,不要带末尾
controller子路径 - 改完后必须执行
php think clear:route,否则缓存仍用旧扫描结果
路由能访问但参数为空?检查变量规则和 method 匹配
比如写了 #[Route("user/:id")],访问 /user/123 却收不到 $id,常见原因有两个:
- 没指定
method,而当前请求是 POST,但注解默认只注册 GET 路由(#[Get]显式限定 GET,#[Route]不写method默认也是 GET) - 变量未定义规则,
:id允许任意字符,但框架内部可能因正则不匹配导致参数丢弃;建议加pattern:#[Route("user/:id", pattern: ["id" => "d+"])] - URL 中有大小写或特殊字符,而默认变量规则不兼容;可全局设置
config/route.php中的'param_convert' => false关闭自动类型转换
最稳妥的做法是:所有带变量的 #[Route] 都显式声明 method 和 pattern,不依赖默认行为。

