Slim 4 在没有 $app 的情况下将所有路由放入控制器

Slim 4 get all routes into a controller without $app

我需要将所有已注册的路由用于控制器。 在 slim 3 中,可以通过

获得路由器
$router = $container->get('router');
$routes = $router->getRoutes();

使用 $app 很容易$routes = $app->getRouteCollector()->getRoutes();

有什么想法吗?

如果您使用 PHP-DI,您可以添加容器定义并通过构造函数注入来注入对象。

示例

<?php

// config/container.php

use Slim\App;
use Slim\Factory\AppFactory;
use Slim\Interfaces\RouteCollectorInterface;

// ...

return [
    App::class => function (ContainerInterface $container) {
        AppFactory::setContainer($container);

        return AppFactory::create();
    },

    RouteCollectorInterface::class => function (ContainerInterface $container) {
        return $container->get(App::class)->getRouteCollector();
    },

    // ...
];

动作class:

<?php

namespace App\Action\Home;

use Psr\Http\Message\ResponseInterface;
use Slim\Http\Response;
use Slim\Http\ServerRequest;
use Slim\Interfaces\RouteCollectorInterface;

final class HomeAction
{
    /**
     * @var RouteCollectorInterface
     */
    private $routeCollector;

    public function __construct(RouteCollectorInterface $routeCollector)
    {
        $this->routeCollector = $routeCollector;
    }

    public function __invoke(ServerRequest $request, Response $response): ResponseInterface
    {
        $routes = $this->routeCollector->getRoutes();

        // ...
    }
}

这将显示有关 SlimPHP 4 应用中所有路由的基本信息:

$app->get('/tests/get-routes/', function ($request, $response, $args) use ($app) {
    $routes = $app->getRouteCollector()->getRoutes();
    foreach ($routes as $route) {
        echo $route->getIdentifier() . " → ";
        echo ($route->getName() ?? "(unnamed)") . " → ";
        echo $route->getPattern();
        echo "<br><br>";
    }

    return $response;
});

从那里,可以使用类似这样的东西来获取给定路线的 URL:

$routeParser = \Slim\Routing\RouteContext::fromRequest($request)->getRouteParser();
$path = $routeParser->urlFor($nameofroute, $data, $queryParams);

有以下注意事项:

  • 这仅适用于命名路由;
  • 这只有在提供了必需的路由参数时才有效——而且没有方法来检查路由是否采用强制性或可选路由参数。
  • 无法获取未命名路线的 URL。