Reputation: 11
For example, lets say I have this route.
<?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, ]);
Here is how I handle routes, and call the controller and its method.
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;
}
How do I pass {slug} to the controller method? It doesn't mention anything about it in its documentation, and no information about it can be found via a google search.
Upvotes: 1
Views: 2852
Reputation:
I didn't work with DICE until now, though I looked in its implementation in order to present the first option to you. I hope it will work. If not, feel free to read the DICE documentation/code regarding the call
rule and the create
method.
Note: The title should be something like "FastRoute: Pass route parameters to handler", or "FastRoute: Pass route arguments to handler", because a prefix is defined as the route part which is prepended to each route pattern inside of a route group.
call
rule of the DI container (DICE):This is, of course, the recommended way, since the DI container automatically injects the method arguments. Which could be more than the ones read from the route!
Note: controller method =: "action".
See (in DICE docs):
call
rule in 3. Configuring the container with Dice Rules.Route:
$router->addRoute('GET', '/{userName}[/{userId:\d+}]', ['UserController', 'list']);
Note: if you have optional route parts, then you have to define the corresponding action parameters as optional.
Dispatching request by 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;
Action in UserController:
public function list($userName, $userId = NULL) {
return 'User name = ' . $userName . ', User id = ' . $userId ?? 'N/A';
}
Route:
The same.
Dispatching request by 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;
Action in UserController:
public function list($userName, $userId = NULL) {
return 'User name = ' . $userName . ', User id = ' . $userId ?? 'N/A';
}
Assign the route parameters list to a Request
instance (See PSR-7), as attribute, and pass the instance as action argument.
Route:
The same.
DI container definitions:
// Share a Request instance.
$dice->addRule('Request', ['shared' => true]);
Dispatching request by 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;
Action in 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';
}
Upvotes: 1