FastRoute: передать префикс маршрута обработчику

Например, допустим, у меня есть этот маршрут.

<?php declare(strict_types = 1);

$dispatcher = FastRoute\cachedDispatcher(function(FastRoute\RouteCollector $router) {

$router->addRoute('GET', '/{slug}', ['App\Controllers\SomeController', 'someMethod']);

}, [ 'cacheFile' => ROOT . '/storage/cache/route.cache', 'cacheDisabled' => true, ]);

Вот как я обрабатываю маршруты и вызываю контроллер и его метод.

switch ($routeInfo[0]) {
case FastRoute\Dispatcher::NOT_FOUND:
echo '404 Not Found';
break;
case FastRoute\Dispatcher::METHOD_NOT_ALLOWED:
$allowedMethods = $routeInfo[1];
echo '405 Method Not Allowed';
break;
case FastRoute\Dispatcher::FOUND:
$controller = $dice->create($routeInfo[1][0]);
echo $controller->{$routeInfo[1][1]}($routeInfo[2]);
break;
}

Как мне передать {slug} в метод контроллера? Он ничего не упоминает об этом в своей документации, и никакой информации о нем нельзя найти с помощью поиска Google.

1

Решение

Я не работал с DICE до сих пор, хотя я посмотрел в его реализации, чтобы представить вам первый вариант. Я надеюсь, что это сработает. Если нет, не стесняйтесь читать документацию / код DICE относительно call править и create метод.

Примечание: заголовок должен выглядеть примерно так: «FastRoute: Pass route параметры to handler «, или» FastRoute: пройти маршрут аргументы к обработчику «, потому что префикс определяется как часть маршрута, которая добавляется к каждому шаблону маршрута внутри группы маршрутов.

Вариант 1. Используйте call Правило контейнера DI (DICE):

Это, конечно, рекомендуемый способ, поскольку контейнер DI автоматически вводит аргументы метода. Который может быть больше, чем те, которые прочитаны с маршрута!

Примечание: метод контроллера =: «действие».

Смотрите (в DICE документах):

Маршрут:

$router->addRoute('GET', '/{userName}[/{userId:\d+}]', ['UserController', 'list']);

Примечание: если у вас есть дополнительные части маршрута, то вы должны определить соответствующие параметры действия как дополнительные.

Запрос отправки FastRoute:

case FastRoute\Dispatcher::FOUND:
$controllerName = $routeInfo[1][0]; // "UserController"$action = $routeInfo[1][1]; // "list" action
$parameters = $routeInfo[2]; // Action parameters list (e.g. route parameters list)

$rule['call'] = [ // Define the method to be called and the parameters to be passed to the further created controller.
[$action, $parameters],
];

$dice->addRule($controllerName, $rule);

$controller = $dice->create($controllerName); // UserController instance

break;

Действие в UserController:

public function list($userName, $userId = NULL) {
return 'User name = ' . $userName . ', User id = ' . $userId ?? 'N/A';
}

Вариант 2. Вызвать действие (без DICE), отдельно передав ему все параметры маршрута:

Маршрут:

Такой же.

Запрос отправки FastRoute:

case FastRoute\Dispatcher::FOUND:
$controllerName = $routeInfo[1][0]; // "UserController"$action = $routeInfo[1][1]; // "list" action
$parameters = $routeInfo[2]; // Action parameters list (e.g. route parameters list)

$controller = $dice->create($controllerName); // UserController instance

call_user_func_array(
[$controller, $action] // callable
, $parameters
);

break;

Действие в UserController:

public function list($userName, $userId = NULL) {
return 'User name = ' . $userName . ', User id = ' . $userId ?? 'N/A';
}

Вариант 3: вызвать действие (без DICE), передав экземпляр класса Request:

Назначить список параметров маршрута Request экземпляр (см. PSR-7), как атрибут, и передать экземпляр в качестве аргумента действия.

Маршрут:

Такой же.

Определения контейнера DI:

// Share a Request instance.
$dice->addRule('Request', ['shared' => true]);

Запрос отправки FastRoute:

case FastRoute\Dispatcher::FOUND:
$controllerName = $routeInfo[1][0]; // "UserController"$action = $routeInfo[1][1]; // "list" action
$parameters = $routeInfo[2]; // Action parameters list (e.g. route parameters list)

// Create Request instance.
$request = $dice->create('Request');

// Assign the route parameters list to the Request instance.
$request->setAttribute('parameters') = $parameters

$controller = $dice->create($controllerName); // UserController instance

call_user_func_array(
[$controller, $action] // callable
, [$request]
);

break;

Действие в UserController:

public function list(ServerRequestInterface $request) {
$userName = $request->getAttribute('parameters')['userName'];
$userId = $request->getAttribute('parameters')['userId'] ?? 'N/A';

return 'User name = ' . $userName . ', User id = ' . $userId ?? 'N/A';
}
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]