对于一些日志记录/监控,我想获得当前的路由路径,包括占位符。如果我的路由是/blog/{slug},请求是http://localhost/blog/foobar,那么我需要的是“/blog/{slug}”在请求侦听器中,这个值似乎不在请求对象中。我只找到了我不感兴趣的解析路径。在编译器传递中,我遇到了一个问题,即我试图从ContainerBuilder获取的任何与路由器相关的服务都返回异常。什么是一个干净的方式来获得它?
apeeds0o1#
您可以获取Router和RouteCollection,它们包含应用中的所有路线:
Router
RouteCollection
// 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。
ConfigCache
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;
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(); } }
3条答案
按热度按时间apeeds0o1#
您可以获取
Router
和RouteCollection
,它们包含应用中的所有路线:注意:不建议在运行时使用
RouteCollection
,因为它会触发重新编译。正如这条GitHub评论所指出的,正确的方法是在缓存预热时使用ConfigCache
。vjhs03f72#
对于具有一个参数的路由:
对于具有多个参数的路由:
cngwdvgl3#
可以使用Reflection API