可直接从$request的Dispatched::class属性提取:$dispatched=$this->request->getAttribute(Dispatched::class),再取$dispatched->handler->callback字符串,用explode('@', $callback)拆分并截取命名空间后类名,即可得控制器名和方法名;完整路由路径用$request->path()获取。

能直接拿到控制器类名、方法名和完整路由路径,但必须从 $request 的属性中取,不能靠全局函数或 Router 实例查。
怎么从 request 中提取 controller 和 action 名称
Hyperf 在路由匹配完成后,会把解析结果存进 $request 的 Dispatched::class 属性里,里面包含一个 handler->callback 字符串,格式是 "AppControllerIndexController@index"。
- 必须先确保请求已进入控制器方法(即在
AbstractController子类中调用),否则getAttribute(Dispatched::class)会返回null -
callback是字符串,不是数组或对象;v2.2和v3.0+行为一致,但 v3.0+ 的Dispatched类增加了更多字段(如route) - 不要用
get_called_class()或__METHOD__替代——它们返回的是当前类/方法,不是实际被路由匹配到的(比如中间件里调用就错)
示例代码:
use HyperfHttpServerRouterDispatched;
public function index()
{
$dispatched = $this->request->getAttribute(Dispatched::class);
if (! $dispatched || ! $dispatched->handler) {
return 'no route matched';
}
$callback = $dispatched->handler->callback; // string
[$class, $method] = explode('@', $callback);
$controller = substr(strrchr($class, '\'), 1); // 去掉命名空间
return compact('controller', 'method');
}
怎么获取当前请求的完整路由路径(不带域名和 query)
用 $request->path() 最稳妥,它返回的是原始 URI 的 path 部分,不含查询参数,也不受重写影响。
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
-
$request->url()返回带协议和域名的完整 URL,不适合做路由判断 -
$request->fullUrl()包含 query string,容易因参数不同导致误判 -
$request->getUri()->getPath()效果同path(),但多一层对象访问,没必要 - 注意:如果用了
addGroup('/api')或@Controller("/admin"),path()返回的是完整路径(如/admin/user/list),不是去前缀后的
为什么不能用 Router::getCurrentRoute() 或类似方法
Hyperf 的 Router 类没有提供运行时“当前路由”查询接口,它的职责是匹配,不是记录上下文。所有路由信息只在匹配瞬间注入 $request,之后就不再维护。
- 试图调用
$container->get(Router::class)->getRoutes()拿到的是全部注册路由,不是当前匹配项 -
Router::getDispatcher()返回的是 FastRoute 的Dispatcher实例,无法反查当前匹配结果 - 某些第三方包封装了“当前路由”辅助方法,但底层仍是读
Dispatched,属于重复造轮子
动态路由下 Dispatched 信息还可靠吗
可靠,前提是动态路由已生效且请求成功匹配——因为每次请求都会走一遍 FastRoute 的 dispatch(),新 dispatcher 生成的 Dispatched 结构与静态路由完全一致。
- 如果你用
DynamicRouteProvider替换了路由表,并调用Router::setDispatcher()(v3.0+)或反射更新(v2.2),那$request->getAttribute(Dispatched::class)就是新路由的结果 - 但要注意:若动态加载失败、回滚未触发、或 dispatcher 未正确替换,
Dispatched可能为空或指向旧路由 - 建议加一层空值 guard:
if (! $dispatched || ! $dispatched->handler || ! is_string($dispatched->handler->callback)) { ... }
真正容易被忽略的是:Dispatched 对象只在路由中间件之后才注入,所以如果你在自定义中间件里过早访问它,可能还是 null —— 务必确认中间件执行顺序在 CoreMiddleware 之后。


















