我有一个控制器,它实现了所有路由/URL。
我想提供一个通用的索引来展示所有帮助页面。
在Symfony2
中,有没有一种方法可以在控制器内获取由控制器定义的所有路由?
我有一个控制器,它实现了所有路由/URL。
我想提供一个通用的索引来展示所有帮助页面。
在Symfony2
中,有没有一种方法可以在控制器内获取由控制器定义的所有路由?
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组件中router:debug命令使用的相同方法):
/**
* @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) {
}
}
}
路由.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
等。
你可以获取所有路由,然后从中创建一个数组,再将该控制器的路由传递给你的twig。
这不是一种优美的方式,但它在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 ;
@Route("/news")
。当我尝试使用您的方法时,因为没有 name="news_route"
参数,我无法获取到此路由。有人遇到过类似的问题吗? - Dimitry Kname = news_route
只是覆盖此默认操作)。 因此,对于Bills \ BlogBundle
,NewsController
,indexAction
,名称将自动生成为bills_blog_news_index
。 - qooplmao我正想做到这一点,在搜索代码后,我想出了这个解决方案,适用于单个控制器(或任何资源)。 适用于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)
}
如果有人遇到这个问题,这是我在全局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'
<script></script>
在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
------------------------------------------------------------------------- -------------------------------------
最安全的方法是使用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
}
因为您需要从控制器中获取路由信息,所以可以利用Symfony的自动装配。如果配置正确,您只需将RouterInterface
传递给控制器中的任何路由即可。
#[Route('/', name: 'app_default')]
public function someRoute(RouterInterface $router): JsonResponse
{
$routesPaths = [];
foreach ($router->getRouteCollection()->all() as $routeName => $route) {
$routesPaths["$routeName"] = $route->getPath();
}
return new JsonResponse([
'availableRoutes' => $routesPaths,
]);
}
然而,如果您需要在多个控制器中使用此逻辑,则应该将逻辑封装在一个单独的类中,就像@C Alex在他的答案中所做的那样。
router:debug
中找到此路由的提及...有什么想法吗? - Dimitry K