【问题标题】:How to get list of all routes of a controller in Symfony2?如何在 Symfony2 中获取控制器的所有路由列表?
【发布时间】:2013-04-03 08:28:06
【问题描述】:

我有一个控制器,它实现了所有路由/URL。 我的想法是为所有帮助页面提供一个通用索引。

有没有办法在Symfony2 中获取控制器(从控制器内)定义的所有路由?

【问题讨论】:

    标签: symfony indexing controller routes symfony-2.1


    【解决方案1】:

    您可以做的是将 cmd 与(最高 SF2.6)一起使用

    php app/console router:debug
    

    对于 SF 2.7,命令是

    php app/console debug:router
    

    对于 SF 3.0,命令是

    php bin/console debug:router
    

    显示所有路线。

    如果您为每个控制器定义一个前缀(我推荐),例如,您可以使用

    php app/console router:debug | grep "<prefixhere>"
    

    显示所有匹配的路线

    在控制器中显示获取所有路由,输出基本相同 我会在控制器中使用以下内容(它与路由器中使用的方法相同:symfony 组件中的调试命令)

    /**
     * @Route("/routes", name="routes")
     * @Method("GET")
     * @Template("routes.html.twig")
     *
     * @return array
     */
    public function routeAction()
    {
        /** @var Router $router */
        $router = $this->get('router');
        $routes = $router->getRouteCollection();
    
        foreach ($routes as $route) {
            $this->convertController($route);
        }
    
        return [
            'routes' => $routes
        ];
    }
    
    
    private function convertController(\Symfony\Component\Routing\Route $route)
    {
        $nameParser = $this->get('controller_name_converter');
        if ($route->hasDefault('_controller')) {
            try {
                $route->setDefault('_controller', $nameParser->build($route->getDefault('_controller')));
            } catch (\InvalidArgumentException $e) {
            }
        }
    }
    

    routes.html.twig

    <table>
    {% for route in routes %}
        <tr>
            <td>{{ route.path }}</td>
            <td>{{ route.methods|length > 0 ? route.methods|join(', ') : 'ANY' }}</td>
            <td>{{ route.defaults._controller }}</td>
        </tr>
    {% endfor %}
    </table>
    

    输出将是:

    /_wdt/{token} ANY web_profiler.controller.profiler:toolbarAction 等等

    【讨论】:

    • 对不起!我想从控制器中访问这些信息,以便它可以生成索引。
    • 我怀疑路由组件确实关心控制器。
    • 这意味着什么?有没有机会获得这些信息?
    • 我强烈建议阅读 symfony 中的路由和依赖注入,你的工具应该是:symfony.com/doc/master/book/routing.htmlsymfony.com/doc/current/components/dependency_injection/…
    • 我读到了,但我只是在寻找一种从控制器 (php) 中获取控制器配置路由的方法。 Qoop 的回答有所帮助。谢谢
    【解决方案2】:

    您可以获取所有路由,然后从中创建一个数组,然后将该控制器的路由传递给您的树枝。

    这不是一个漂亮的方法,但它可以工作..无论如何对于 2.1..

        /** @var $router \Symfony\Component\Routing\Router */
        $router = $this->container->get('router');
        /** @var $collection \Symfony\Component\Routing\RouteCollection */
        $collection = $router->getRouteCollection();
        $allRoutes = $collection->all();
    
        $routes = array();
    
        /** @var $params \Symfony\Component\Routing\Route */
        foreach ($allRoutes as $route => $params)
        {
            $defaults = $params->getDefaults();
    
            if (isset($defaults['_controller']))
            {
                $controllerAction = explode(':', $defaults['_controller']);
                $controller = $controllerAction[0];
    
                if (!isset($routes[$controller])) {
                    $routes[$controller] = array();
                }
    
                $routes[$controller][]= $route;
            }
        }
    
        $thisRoutes = isset($routes[get_class($this)]) ?
                                    $routes[get_class($this)] : null ;
    

    【讨论】:

    • 这就是我错过的: $router = $this->container->get('router'); $collection = $router->getRouteCollection(); $allRoutes = $collection->all(); THX
    • 但这不会显示没有定义名称的路由,例如。 @Route("/news")。当我尝试您的方法时,因为没有 name="news_route" 参数,我无法提到这条路线。有人遇到过类似问题吗?
    • 据我所知,如果您使用注释并且不声明名称,那么名称是从包名称、控制器名称和操作名称自动生成的,(使用 name=news_route只是覆盖此默认操作)。因此对于Bills\BlogBundleNewsControllerindexAction,名称将自动生成为bills_blog_news_index
    【解决方案3】:

    我正打算这样做,在搜索代码后,我想出了这个适用于单个控制器(或实际上任何资源)的解决方案。适用于 Symfony 2.4(我没有使用以前的版本进行测试):

    $routeCollection = $this->get('routing.loader')->load('\Path\To\Controller\Class');
    
    foreach ($routeCollection->all() as $routeName => $route) {
       //do stuff with Route (Symfony\Component\Routing\Route)
    }
    

    【讨论】:

    • 获取控制器所有操作(路由)的有趣方式。
    • 迄今为止的最佳答案
    【解决方案4】:

    在 Symfony 4 中,我想在一个列表中获取所有路由,包括控制器和操作。在 Rails 中,默认情况下你可以得到这个。

    在 Symfony 中,您需要将参数 show-controllers 添加到 debug:router 命令中。

    如果有人在寻找相同的功能,可以使用:

    bin/console debug:router --show-controllers
    

    这将产生如下列表

    ------------------------------------------------------------------------- -------------------------------------
    Name                   Method    Scheme    Host     Path                    Controller
    ------------------------------------------------------------------------- -------------------------------------
    app_some_good_name     ANY       ANY       ANY      /example/example        ExampleBundle:Example:getExample
    ------------------------------------------------------------------------- -------------------------------------
    

    【讨论】:

      【解决方案5】:

      如果有人在这个问题上遇到困难,这就是我在全局 twig 范围(symfony 4)中导出路由的方式。

      src/Helper/Route.php

      <?php
      
      namespace App\Helper;
      
      use Symfony\Component\Routing\RouterInterface;
      
      class Routes
      {
          private $routes = [];
      
          public function __construct(RouterInterface $router)
          {
              foreach ($router->getRouteCollection()->all() as $route_name => $route) {
                  $this->routes[$route_name] = $route->getPath();
              }
          }
      
          public function getRoutes(): array
          {
              return $this->routes;
          }
      }
      

      src/config/packages/twig.yaml

      twig:
          globals:
              route_paths: '@App\Helper\Routes'
      

       

      然后在你的 twig 文件中填充一个 javascript 变量以在你的脚本中使用

      <script>
          var Routes = {
              {% for route_name, route_path in routes_service.routes %}
                  {{ route_name }}: '{{ route_path }}',
              {% endfor %}
          }
      </script>
      

      【讨论】:

        【解决方案6】:

        最安全的方法是使用 symfony 控制器解析器,因为您永远不知道您的控制器是否被定义为完全限定的类名、服务或任何可调用的声明。

            foreach ($this->get('router')->getRouteCollection() as $route) {
                $request = new Request();
                $request->attributes->add($route->getDefaults());
        
                [$service, $method] = $this->resolver->getController($request);
        
                // Do whatever you like with the instanciated controller
            }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-05-22
          • 2013-05-19
          • 2012-10-13
          • 1970-01-01
          • 2015-01-13
          • 1970-01-01
          相关资源
          最近更新 更多