如何从 URI 路径参数中获取关联数组?

How to get an associative array from URI path parameters?

我正在使用 Symfony/Routing 组件设置路由并将它们映射到各自的控制器和操作。

问题是某些操作(方法)接收多个参数,我想解决这个问题,将数组从 URL 中设置的参数传递到它正在调用的方法。

(我简化了定义路由的API,所以看起来有点 代码示例不同)

 //setting new route
 Route::add('user_introduce_route',
        '/user/{name}/{$age}/{$profession}',
        ['controller' => 'App\Controllers\User.introduce'], 
        ['name' => '[a-zA-Z0-9]+', 'age' => '[0-9]+', 'profession' => '[[a-zA-Z]+]']
 );

当我浏览 /user/myuser01/programmer 时,它调用 introduceAction() 在我的 UserController[= 中设置27=] 并且我想将这三个参数一起传递给该方法。以下是我如何调用该方法:

public static function startRouting()
{
    $parameters = self::matchUrl(); //UrlMatcher->match()

    $class = explode('.', $parameters['controller'])[0];
    $method = explode('.', $parameters['controller'])[1];

    $class::$method(); //here I would like to pass the array with the parameters
}

在这种情况下,我想做的是从 URL 中的参数中检索一个关联数组,并传递给仅调用名称、年龄和职业 slugs 的方法。

如果您能帮助我或知道任何其他解决此问题的方法,我将不胜感激。

据我所知,有两个规范的解决方案,其中第二个稍微复杂一些。和一个额外的解决方案,需要更改您当前的路由定义方法,但我更喜欢这种解决方案。

使用 $parameters

因为 $parameters 已经包含了来自 slug 的所有正确名称的数据,我们可以删除/过滤掉控制器(和其他一般 well-known 条目,如果有的话):

unset($parameters['controller']);
unset($parameters['_route']); // <-- should be there
$class::$method($parameters);

使用路线要求

我希望你仍然拥有你提供给 url 匹配器的路由集合:

$requirements = $routecollection->get($parameters['_route'])->getRequirements();
$reduced = [];
foreach(array_keys($requirements) as $key) {
    // ?? null, in case there are optional route params?
    $reduced[$key] = $parameters[$key] ?? null;
}
$class::$method($reduced);

据我所知,每个路由参数都必须是一个要求,所以...是的。除非你有一些非常非常复杂的路由和奇怪的正则表达式,否则这应该有效,并且可能是未来向你的路由添加更多 non-path 参数的证据。

改变你的路线(奖金,我的偏好)

symfony 框架也使用路由。然而,每个 non-path 路由参数总是以 _ 为前缀,这使得它很容易被过滤掉。如果你相应地改变你的路由定义(将 'controller' 变成 '_controller'),你可以很容易地过滤掉参数:

//$class = explode('.', $parameters['_controller'])[0];
//$method = explode('.', $parameters['_controller'])[1];
// different here -------------------^^ 

$reduced = [];
foreach($parameters as $key => $value) {
    if($key[0] != '_') { 
        $reduced[$key] = $value;
    }
}
$class::$method($reduced);

并且路由定义显然必须进行调整,如前所述。