在Symfony中获取当前请求的路由路径'/blog/{slug}'

r6l8ljro  于 2023-03-30  发布在  其他
关注(0)|答案(3)|浏览(111)

对于一些日志记录/监控,我想获得当前的路由路径,包括占位符。
如果我的路由是/blog/{slug},请求是http://localhost/blog/foobar,那么我需要的是“/blog/{slug}”
在请求侦听器中,这个值似乎不在请求对象中。我只找到了我不感兴趣的解析路径。
在编译器传递中,我遇到了一个问题,即我试图从ContainerBuilder获取的任何与路由器相关的服务都返回异常。
什么是一个干净的方式来获得它?

apeeds0o

apeeds0o1#

您可以获取RouterRouteCollection,它们包含应用中的所有路线:

// 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)
    {
        // This is for sf53 and up, for previous versions, use isMasterRequest()
        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());
    }
}

注意:不建议在运行时使用RouteCollection,因为它会触发重新编译。正如这条GitHub评论所指出的,正确的方法是在缓存预热时使用ConfigCache

vjhs03f7

vjhs03f72#

对于具有一个参数的路由:

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

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

echo $routeDefinition;

对于具有多个参数的路由:

$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;
cngwdvgl

cngwdvgl3#

可以使用Reflection API

<?php

class SomeController extends AbstractController
{
    #[Route('/catalog/item/{itemId}')]
    public function foo(){
        $class     = new \ReflectionClass(__CLASS__);
        $method    = $class->getMethod(__FUNCTION__);
        $routeAttr = $method->getAttributes(Route::class)[0];
        $routePath = $routeAttr->newInstance()->getPath();
        var_dump($routePath); 
        die();
    }

}

相关问题