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

时间:2019-05-13 18:50:53

标签: php symfony slug symfony-routing

我正在使用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 时,它会调用 UserController 中设置的 introduceAction(),我想传递这三个参数一起使用的方法。这是我调用该方法的方式:

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中的参数中检索一个关联数组,并将其传递给仅被称为姓名,年龄和专业人士的方法。

对于这个问题,如果您可以帮助我或知道其他解决方法,

1 个答案:

答案 0 :(得分:1)

据我所知,有两种规范的解决方案,其中第二种更为详尽。和额外的解决方案,这需要更改您当前的路由定义方法,但是我更喜欢这种解决方案。

使用$parameters

由于$parameters已包含来自子弹的所有具有正确名称的数据,因此我们可以删除/过滤控制器(以及其他一般的知名条目,如果有的话):

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

使用路线要求

希望您仍然有提供给url匹配器的routecollection:

$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);

据我所知,每个路由参数都必须是一个要求,所以...是的。除非您有一些带有非常奇怪的正则表达式的非常非常复杂的路由,否则这应该起作用,并且可能为将来在向路由中添加更多非路径参数提供证明。

更改您的路线(奖励,请按我的喜好)

symfony框架也使用路由。但是,每个非路径路由参数始终以_为前缀,这使得过滤非常容易。如果您要相应地更改路线定义(将'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);
如前所述,

和路由定义显然必须进行修改。