如何在Symfony 2中获取当前路线?


Answers:


323

从ContainerAware(例如控制器)中:

$request = $this->container->get('request');
$routeName = $request->get('_route');


37
github.com/symfony/symfony/issues/854 request.attributes.get('_ route')不可靠,因为它仅用于调试目的(symfony dev说),并且如果转发请求则不起作用...请参见超新星的回答有据可查,而且更加安全可靠
luiges90

3
转发某些内容时此操作不起作用的原因是由于您直接转发到控制器而不是路由。因此,Symfony不知道这是干什么的。通常,您只有一条通往一个控制器的路由,因此看起来很奇怪,除了“ _internal”之外,它什么都没有报告,但是,可以创建与多个路由定义相关联的通用控制器。当您考虑所有这些时,我认为这种“陷阱”更有意义。
jzimmerman2011 2014年

@ tuxedo25考虑使用RequestStack:symfony.com/blog/new-in-symfony-2-4-the-request-stack
mYkon

2
$ request-> get('_ route'); 是慢的 !$ request-> attributes-> get('_ route'); 如果您不需要灵活性,那就更好了
Tom Tom

190

与树枝: {{ app.request.attributes.get('_route') }}


8
谢谢!我正在<body class="{{ app.request.get('_route') | replace({'_' : '-'}) }}">应用特定于页面的CSS :)
Salman von Abbas 2012年

10
github.com/symfony/symfony/issues/854 request.attributes.get('_ route')不可靠,因为它仅用于调试目的(symfony dev说),并且如果转发请求则不起作用...请参见超新星的回答有据可查,而且更加安全可靠
luiges90

48

我认为这是最简单的方法:

class MyController extends Controller
{
    public function myAction($_route)
    {
        var_dump($_route);
    }

    .....

3
您是否可以添加更多说明或显示示例输出来阐明这是如何解决问题的?
查理


1
@Charlie这是一个预定义变量,为您提供匹配的路由“名称”
超新星

2
这绝对是对原始问题的最佳答案。附带说明:但是,对于子请求(如){% render "SomeBundle:SomeController:someAction" %},它不起作用,您将再次获得值“ _internal”。
netmikey

2
可惜的是,这仅适用于原始Action,因为必须转发其他任何功能。
DarekWędrychowski13年

27

Symfony 2.0-2.1
使用此:

    $router = $this->get("router");
    $route = $router->match($this->getRequest()->getPathInfo());
    var_dump($route['_route']);

那一个不会给你的_internal

Symfony 2.2+的更新:从Symfony 2.2+开始,此功能不起作用。我打开一个错误,答案是“按设计”。如果您希望在子操作中获取路线,则必须将其作为参数传递

{{ render(controller('YourBundle:Menu:menu', { '_locale': app.request.locale, 'route': app.request.attributes.get('_route') } )) }}

和您的控制器:

public function menuAction($route) { ... }

github.com/symfony/symfony/issues/854我对此不确定,$route['_route']似乎有问题,但可能不是symfony开发人员所谈论的。该食谱没有提及_route$router->match()输出..
luiges90

我完全同意@ luiges90。的PHPDoc $router->match()说“ @return array一个参数数组”似乎内部。我不想依靠它,但是现在,它似乎是处理子请求时唯一可行的解​​决方案。
netmikey

19

没有适用于所有用例的解决方案。如果使用$ request-> get('_ route')方法或其变体,在发生转发的情况下它将返回'_internal'

如果您需要即使转发也可以使用的解决方案,则必须使用2.4中提供的新RequestStack服务,但这会中断ESI支持

$requestStack = $container->get('request_stack');
$masterRequest = $requestStack->getMasterRequest(); // this is the call that breaks ESI
if ($masterRequest) {
    echo $masterRequest->attributes->get('_route');
}

如果在模板中需要它,可以使用它来进行细枝扩展。


那么……您的解决方案如何不能完全适用于所有用例?
greg0ire

11

_route不是走的路,从来没有。创建Symfony的Fabien 始终将其用于调试目的。这是不可靠的,因为它不适用于转发和对控制器的其他直接调用(如部分渲染)。

您需要在控制器中注入路线名称作为参数,请参阅此处的文档

另外,$request->get('');如果您不需要灵活性,请不要使用它,它比使用所需的特定属性包(属性,查询或请求)上的get慢得多,因此$request->attributes->get('_route');在这种情况下。


4
好的,您基本上建议向此文件中的每个路由添加额外的信息,而不是获取路由名称?…
Charaf

1
是的,特别是如果您需要稍后在行中调用控制器本身(转发,部分渲染等),将名称作为参数传递是此处的唯一方法,因为您根本不会调用路由案件。至于用于调试目的的_route,请不要对我吐露^^'
Tom Tom


4

我从中得到的就是 _internal

我从控制器内部获取路由名称,$this->getRequest()->get('_route'). 甚至代码tuxedo25建议返回_internal

该代码在Symfony 1.X中称为“组件”的位置执行。不是页面的控制器,而是页面的一部分,需要某些逻辑。

Symfony 1.X中的等效代码为: sfContext::getInstance()->getRouting()->getCurrentRouteName();


2
我自己解决了。认为:$view['request']->getParameter('_route');
alexismorin 2011年

5
这是因为您正在通过进行{% render... %}呼叫standalone=true。启用缓存(AppCache.php或具有ESI的清漆)后,这将导致使用单独的HTTP-Request(这是路由_internal起作用的位置)来请求独立视图的顺序,以便可独立缓存。
MartinSchuhfuß2012年

2

在Symfony 3.3中,我使用了这种方法并且运行良好。

我有4条路线,例如

admin_category_index,admin_category_detail,admin_category_create,admin_category_update

只需一行就可以成为所有路线的活跃课程。

<li  {% if app.request.get('_route') starts with 'admin_category' %} class="active"{% endif %}>
 <a href="{{ path('admin_category_index') }}">Product Categoires</a>
</li>

1

要基于URL获取当前路由(在转发情况下更可靠):

public function getCurrentRoute(Request $request)
{
    $pathInfo    = $request->getPathInfo();
    $routeParams = $this->router->match($pathInfo);
    $routeName   = $routeParams['_route'];
    if (substr($routeName, 0, 1) === '_') {
        return;
    }
    unset($routeParams['_route']);

    $data = [
        'name'   => $routeName,
        'params' => $routeParams,
    ];

    return $data;
}

0

使用Symfony 4.2.7,我可以在树枝模板中实现以下内容,该模板显示我在控制器中定义的自定义路由名称。

在index.html.twig中

<div class="col">
    {% set current_path =  app.request.get('_route') %}
    {{ current_path }}
</div>

在我的控制器中


    ...

    class ArticleController extends AbstractController {
        /**
         * @Route("/", name="article_list")
         * @Method({"GET"})
         */
        public function index() {
        ...
        }

        ...
     }

结果将“ article_list”打印到我的浏览器中所需的页面。


0

对于需要Symfony 3当前路线的任何人,这就是我使用的

<?php
   $request = $this->container->get('router.request_context');
   //Assuming you are on user registration page like https://www.yoursite.com/user/registration
   $scheme = $request->getScheme(); //This will return https
   $host = $request->getHost(); // This will return www.yoursite.com
   $route = $request->getPathInfo(); // This will return user/registration(don't forget this is registrationAction in userController
   $name = $request->get('_route'); // This will return the name.
?>

3
这将不会返回名称的处理路线
尼科·哈泽

@NicoHaase这不是火箭科学,您已经有了请求对象
Aderemi Dayo

-2

如果要在控制器中获取路由名称,则必须注入请求(而不是由于Symfony UPGRADE 而从容器获取,而是调用get('_ route')。

public function indexAction(Request $request)
{
    $routeName = $request->get('_route');
}

如果要在树枝中获取路线名称,则必须像

{{ app.request.attributes.get('_route') }}

1
不建议$request->get()直接使用它,因为它很慢:github.com/symfony/http-foundation/blob/2.8/Request.php#L712
ricko zoe 16-11-19
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.