Home > other >  Get route path '/blog/{slug}' of current request in Symfony
Get route path '/blog/{slug}' of current request in Symfony

Time:02-11

For some logging/monitoring i would like to get the current route path including placeholders.

If my route is /blog/{slug} and the request is to http://localhost/blog/foobar what i need is "/blog/{slug}"

In request listeners this value seem to not be inside the request object. I only find the resolved path which i am not interested in.

In Compiler passes I have the issue that any Router related service I try to get from the ContainerBuilder returns an exception. If i had the

What is a clean way to obtain this?

CodePudding user response:

For routes with one param:

$routeWithoutParam = substr($request->getRequestUri(),0,strrpos($request->getRequestUri(),'/'));
$routeParams = $request->attributes->get('_route_params');

$routeDefinition = $routeWithoutParam.'/{' . array_key_first($paramsArray) . '}';

echo $routeDefinition;

For routes with multiple params:

$routeParams = $request->attributes->get('_route_params');
$routeWithoutParam = '';
for ($i = 0; $i < count($routeParams); $i  ) {
   $routeWithoutParam = $i === 0
      ? substr($request->getRequestUri(), 0, strrpos($request->getRequestUri(), '/'))
      : substr($routeWithoutParam, 0, strrpos($routeWithoutParam, '/'))
   ;
}

$routeDefinition = $routeWithoutParam.'/';
foreach (array_keys($routeParams) as $key => $param) {
  $routeDefinition.= '{' . $param . '}' . ($key < count($routeParams)-1 ? '/' : '');
}

echo $routeDefinition;

CodePudding user response:

You can obtain the Router and RouteCollection, that holds all the routes in your app:

// src/Listener/RouteLoggerListener.php -- namespace and use ommited
class RouteLoggerListener implements EventSubscriberInterface
{
    /**
     * @var LoggerInterface
     */
    private $logger;
    /**
     * @var RouterInterface
     */
    private $router;

    public function __construct(LoggerInterface $logger, RouterInterface $router)
    {
        $this->logger = $logger;
        $this->router = $router;
    }

    public static function getSubscribedEvents()
    {
        // Trigger after the RouterListener
        return [KernelEvents::REQUEST => ['onKernelRequest', 50]];
    }

    public function onKernelRequest(RequestEvent $event)
    {
        if (!$event->isMainRequest()) {
            return;
        }

        $request = $event->getRequest();

        if (null == $request) {
            return;
        }

        $matchedRoute = $request->attributes->get('_route');

        if (null == $matchedRoute) {
            // Bail gracefully
            return;
        }

        $routeCollection = $this->router->getRouteCollection();
        $route = $routeCollection->get($matchedRoute);
        $this->logger->debug('Request route: '.$route->getPath());
    }
}

Note: Using RouteCollection at runtime is highly discouraged because it triggers a recompile. As indicated in this GitHub comment, the proper way to do it would be to use ConfigCache while cache warming.

  • Related