FastRoute:将路由前缀传递给处理程序

时间:2018-02-13 04:40:56

标签: php controller routing 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}传递给控制器​​方法?它没有在文档中提及它的任何内容,也没有关于它的信息可以通过谷歌搜索找到。

1 个答案:

答案 0 :(得分:1)

直到现在我还没有和DICE合作过,虽然我查看了它的实现,以便向你展示第一个选项。我希望它能奏效。如果没有,请随时阅读有关call规则和create方法的DICE文档/代码。

注意:标题应该是&#34; FastRoute:将路径参数传递给处理程序&#34;或者&#34; FastRoute:传递路径参数处理程序&#34;,因为前缀被定义为路由部分,它被添加到路由组内的每个路由模式之前。

选项1:使用DI容器的call规则(DICE):

这当然是推荐的方法,因为DI容器会自动注入方法参数。这可能比从路线上读到的更多!

注意:控制器方法=:&#34;动作&#34;。

参见(在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';
}