addroute的基本调用形式为addroute(array $methods, string $path, $handler, array $options = []):$methods必须是数组(如['get']),$path支持静态/动态路径({}必填、[]选填),$handler可为闭包、完整命名空间字符串或数组,$options主要支持middleware和timeout。

addRoute 的基本调用形式和参数顺序
addRoute 是 Hyperf 路由注册的底层方法,比 get/post 等快捷方法更灵活,但参数顺序和类型容易出错。它签名是:addRoute(array $methods, string $path, $handler, array $options = [])。
常见错误是把 $path 和 $handler 位置写反,或传入字符串类名但没加命名空间(如写成 'IndexController@index' 而非 'App\Controller\IndexController@index')。
-
$methods必须是数组,即使只支持一个方法也要写成['GET'],不能传字符串'GET' -
$path支持静态路径('/api/users')、带必填参数('/api/users/{id:\d+}')、选填参数('/api/users/{id:\d+}[/{name}]'),注意{}和[]的语义差异 -
$handler可以是闭包、类方法字符串('App\Controller\UserController@index')、数组形式([Usercontroller::class, 'index']),三者行为一致,但字符串需完整命名空间
为什么 addRoute 注册后访问 404?
最常见原因是路由未被实际加载——addRoute 只是往当前 RouteCollector 实例里加数据,但框架启动后不会自动重刷 FastRoute\Dispatcher。如果你在运行时(比如某个命令或中间件里)调用 addRoute,它不会生效。
正确做法是在 config/routes.php 文件中调用,确保它在服务启动的路由收集阶段执行。若必须动态添加,得手动重建 Dispatcher 并通过 Router::setDispatcher()(v3.0+)或反射替换(v2.2),不是简单调一次 addRoute 就行。
- 检查
config/autoload/server.php中'type' => 'http'是否启用,且端口未被占用 - 执行
php bin/hyperf.php route:list确认该路由是否出现在列表中 - 路径中含正则时(如
{id:\d+}),请求 URL 必须严格匹配,/api/users/abc会 404
addRoute 和 get/post 等快捷方法的区别
get/post 本质是 addRoute 的封装,只固定了 $methods 参数。它们用起来更安全,因为默认做了方法限制和参数校验;而 addRoute 更“裸”,适合需要多方法共用同一 handler 或精细控制 $options 的场景。
比如要让一个接口同时响应 GET 和 HEAD,又想加中间件和超时配置,用 addRoute 更直接:
Router::addRoute(
['GET', 'HEAD'],
'/status',
'App\Controller\HealthController::check',
[
'middleware' => [AuthMiddleware::class],
'timeout' => 3000,
]
);
-
get('/path', ...)等同于addRoute(['GET'], '/path', ...) -
addGroup内部也是调addRoute,前缀拼接发生在内部,不用手动处理 - 所有快捷方法都不支持传
$options,想配中间件或超时,只能用addRoute
addRoute 的 options 参数能做什么
$options 数组目前主要支持两个键:middleware 和 timeout(后者仅对 GatewayRoute 有效,普通 HTTP 路由不识别 timeout)。它不是扩展点,不要往里塞自定义字段。
中间件配置是唯一常用项,值为字符串类名数组,会按顺序执行:
Router::addRoute(
['POST'],
'/upload',
'App\Controller\UploadController::handle',
['middleware' => [AuthMiddleware::class, UploadLimitMiddleware::class]]
);
-
middleware中的中间件必须实现Psr\Http\Server\MiddlewareInterface - 中间件执行顺序 = 数组顺序,
AuthMiddleware在前,UploadLimitMiddleware在后 - 如果用注解路由(
@Middleware),优先级高于$options['middleware'],但两者可共存
真正容易被忽略的是:没有显式声明 middleware 时,这个 key 就不存在,框架不会自动合并全局中间件——它只作用于当前路由,不继承也不覆盖。











