如何配置ThinkPHP8.0的路由规则?

2026-05-20 13:541阅读0评论SEO基础
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计871个文字,预计阅读时间需要4分钟。

如何配置ThinkPHP8.0的路由规则?

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] 才是完整能力入口,middlewaredomainpatternname 都只在这里生效
  • 别在 #[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] 都显式声明 methodpattern,不依赖默认行为。

本文共计871个文字,预计阅读时间需要4分钟。

如何配置ThinkPHP8.0的路由规则?

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] 才是完整能力入口,middlewaredomainpatternname 都只在这里生效
  • 别在 #[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] 都显式声明 methodpattern,不依赖默认行为。