Как получить ассоциативный массив из параметров пути URI? - PullRequest
1 голос
/ 13 мая 2019

Я устанавливаю маршруты с использованием компонента 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 , и я хочу передать эти три параметра вместе метод. Вот как я называю метод:

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 Ответ

1 голос
/ 14 мая 2019

Насколько я могу судить, есть два канонических решения, второе из которых немного сложнее. и бонусное решение, которое требует изменения вашего текущего подхода к определению маршрутизации, но мне это решение нравится больше.

используйте $parameters

, поскольку $parameters уже содержит все данные из слага с правильным именем, мы можем просто удалить / отфильтровать контроллер (и другие общеизвестные записи, если они есть):

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

Насколько я могу судить, каждый параметр маршрута должен быть требованием, так что ... да. Если у вас нет очень очень очень сложных маршрутов со странными регулярными выражениями, это должно сработать и, вероятно, станет будущим доказательством в отношении добавления дополнительных параметров без путей к вашим маршрутам.

измените свой маршрут (бонус будет моим предпочтением)

платформа 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);

и определение маршрутизации, очевидно, должно быть адаптировано, как уже упоминалось.

...