2

I need to get all registed routes to work with into a controller. In slim 3 it was possible to get the router with

$router = $container->get('router');
$routes = $router->getRoutes();

With $app it is easy $routes = $app->getRouteCollector()->getRoutes();

Any ideas?

harley81
  • 190
  • 2
  • 12

2 Answers2

1

If you use PHP-DI you could add a container definition and inject the object via constructor injection.

Example:

<?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();
    },

    // ...
];

The action 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();

        // ...
    }
}

odan
  • 4,757
  • 5
  • 20
  • 49
  • Hi odan, it works but i get an empty array. So i realize that i have to add my routes to the "new" app. – harley81 Jan 10 '20 at 12:37
  • Yes, your routes must be added to the $app instance from the container. `$app = $container->get(App::class);` – odan Jan 10 '20 at 13:08
1

This will display basic information about all routes in your app in 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;
});

From there, one can use something like this to get the URL for a given route:

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

With the following caveats:

  • this will only work for named routes;
  • this will only work if the required route parameters are provided -- and there's no method to check whether a route takes mandatory or optional route parameters.
  • there's no method to get the URL for an unnamed route.
Fabien Snauwaert
  • 4,995
  • 5
  • 52
  • 70