248

How do I get the current route in Symfony 2?

For example, routing.yml:

somePage:
   pattern: /page/
   defaults: { _controller: "AcmeBundle:Test:index" }

How can I get this somePage value?

Moe Far
  • 2,742
  • 2
  • 23
  • 41
IlyaDoroshin
  • 4,659
  • 4
  • 22
  • 26

13 Answers13

347

From something that is ContainerAware (like a controller):

$request = $this->container->get('request');
$routeName = $request->get('_route');
tuxedo25
  • 4,798
  • 1
  • 16
  • 12
  • 2
    @got a switchwation for you check http://meta.stackexchange.com/questions/155258/i-found-answers-for-a-question-not-really-correct-what-i-should-do – NullPoiиteя Nov 10 '12 at 06:35
  • 41
    github.com/symfony/symfony/issues/854 request.attributes.get('_route') is not reliable because it is for debug purpose only (symfony dev said) and does not work if request is forwarded... see supernova's answer which are documented and are more fail-safe – luiges90 Nov 14 '12 at 02:38
  • 3
    The reason for this not working when something is forwarded is due to the fact that you forward directly to a controller, not a route. As such, Symfony doesn't know what route that is for. Typically, you have one route to one controller, so it may seem weird that this can't report anything besides "_internal", however, it is possible to create general-purpose controllers that get associated with more than one route definition. When you consider all of this, I think this "gotcha" makes more sense. – jzimmerman2011 Nov 19 '14 at 20:16
  • @tuxedo25 Think about using RequestStack: http://symfony.com/blog/new-in-symfony-2-4-the-request-stack – mYkon Jun 27 '16 at 09:43
  • 2
    $request->get('_route'); is slow ! $request->attributes->get('_route'); is better if you do not need the flexibility – Tom Tom Dec 17 '16 at 02:24
  • More information here : https://roadtodev.com/comment-recuperer-la-route-actuelle-avec-symfony – Thomas Bredillet Oct 06 '17 at 21:13
  • @ThomasBredillet : The link is down. – sneaky May 09 '20 at 13:05
  • 2
    Since Symfony 4.3 this is officially documented method to get current route name: https://symfony.com/doc/4.3/routing.html#getting-the-route-name-and-parameters – Paweł Napierała Oct 09 '20 at 09:21
194

With Twig : {{ app.request.attributes.get('_route') }}

Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
Matthieu
  • 2,289
  • 2
  • 15
  • 11
  • 8
    Thank you! Am using `` for applying page-specific css :) – Samuel Katz Jul 04 '12 at 16:49
  • 10
    github.com/symfony/symfony/issues/854 request.attributes.get('_route') is not reliable because it is for debug purpose only (symfony dev said) and does not work if request is forwarded... see supernova's answer which are documented and are more fail-safe – luiges90 Nov 14 '12 at 02:39
48

I think this is the easiest way to do this:

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

    .....
supernova
  • 896
  • 8
  • 8
  • 3
    Can you add more explanation or show sample output to clarify how this solves the problem? – Charlie Oct 06 '12 at 18:28
  • 7
    @charlie http://symfony.com/doc/master/book/routing.html#route-parameters-and-controller-arguments – wdev Oct 29 '12 at 11:29
  • 1
    @Charlie It's a predefined variable which gives you the matched route "name" – supernova Oct 31 '12 at 21:46
  • 2
    This is definitely the best answer to the original question. As a side note: it does not work, however, with sub-requests like `{% render "SomeBundle:SomeController:someAction" %}`, where you'll get the value '_internal' again. – netmikey Mar 06 '13 at 10:13
  • 2
    A pity is that this works only in the original Action, for any other function it has to be forwarded. – Darek Wędrychowski May 17 '13 at 18:24
29

Symfony 2.0-2.1
Use this:

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

That one will not give you _internal.

Update for Symfony 2.2+: This is not working starting Symfony 2.2+. I opened a bug and the answer was "by design". If you wish to get the route in a sub-action, you must pass it in as an argument

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

And your controller:

public function menuAction($route) { ... }
jsgoupil
  • 3,788
  • 3
  • 38
  • 53
  • https://github.com/symfony/symfony/issues/854 I am not sure about this, `$route['_route']` seems problematic but might not be symfony dev talks about. The cookbook does not mention about `_route` of `$router->match()` output .. – luiges90 Nov 14 '12 at 02:43
  • I fully agree with @luiges90. The PHPDoc of `$router->match()` says "@return array An array of parameters" which seems _very_ internal. I don't want to rely on it, but right now, it seems to be the only viable solution when dealing with sub-requests. – netmikey Mar 06 '13 at 10:21
21

There is no solution that works for all use cases. If you use the $request->get('_route') method, or its variants, it will return '_internal' for cases where forwarding took place.

If you need a solution that works even with forwarding, you have to use the new RequestStack service, that arrived in 2.4, but this will break ESI support:

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

You can make a twig extension out of this if you need it in templates.

Nathan Craike
  • 5,031
  • 2
  • 24
  • 19
K. Norbert
  • 10,494
  • 5
  • 49
  • 48
11

_route is not the way to go and never was. It was always meant for debugging purposes according to Fabien who created Symfony. It is unreliable as it will not work with things like forwarding and other direct calls to controllers like partial rendering.

You need to inject your route's name as a parameter in your controller, see the doc here

Also, please never use $request->get(''); if you do not need the flexibility it is way slower than using get on the specific property bag that you need (attributes, query or request) so $request->attributes->get('_route'); in this case.

Tom Tom
  • 3,680
  • 5
  • 35
  • 40
  • 4
    Ok, you basically suggest to add extra information to every routes in this files instead of getting the route name ? … – Charaf Feb 22 '17 at 06:50
  • 1
    Yep especially if you need to be able to call the controller itself later down the line (forwards, partial rendering, etc...) passing the name as a parameter is the only way here because you are not calling a route at all in that case. As for _route being meant for debug purposes don't take it out on me ^^' – Tom Tom Feb 26 '17 at 10:24
  • 2
    The doc link is broken. Nevertheless, the corresponding page for the symfony 5.3 version actually states that getting the `_route` is the way to go, actually: https://symfony.com/doc/5.3/routing.html#getting-the-route-name-and-parameters – Xavi Montero Nov 28 '20 at 21:44
9
$request->attributes->get('_route');

You can get the route name from the request object from within the controller.

Venkat Kotra
  • 10,413
  • 3
  • 49
  • 53
4

All I'm getting from that is _internal

I get the route name from inside a controller with $this->getRequest()->get('_route'). Even the code tuxedo25 suggested returns _internal

This code is executed in what was called a 'Component' in Symfony 1.X; Not a page's controller but part of a page which needs some logic.

The equivalent code in Symfony 1.X is: sfContext::getInstance()->getRouting()->getCurrentRouteName();

alexismorin
  • 787
  • 1
  • 6
  • 21
  • 2
    Solved it myself. In a view: `$view['request']->getParameter('_route');` – alexismorin Oct 17 '11 at 14:29
  • 5
    this is because you are using `{% render... %}` calls with `standalone=true`. With caching (AppCache.php or varnish with ESI) enabled this will cause the standalone views to be requested with a seperate HTTP-Request (this is where the route `_internal` comes into play) in order ro be independently cacheable. – Martin Schuhfuß Jun 01 '12 at 13:26
2

For anybody that need current route for Symfony 3, this is what I use

<?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.
?>
Aderemi Dayo
  • 705
  • 1
  • 11
  • 25
2

With Symfony 3.3, I have used this method and working fine.

I have 4 routes like

admin_category_index, admin_category_detail, admin_category_create, admin_category_update

And just one line make an active class for all routes.

<li  {% if app.request.get('_route') starts with 'admin_category' %} class="active"{% endif %}>
 <a href="{{ path('admin_category_index') }}">Product Categoires</a>
</li>
Muhammad Shahzad
  • 9,340
  • 21
  • 86
  • 130
1

To get the current route based on the URL (more reliable in case of forwards):

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;
}
Alain Tiemblo
  • 36,099
  • 17
  • 121
  • 153
0

With Symfony 4.2.7, I'm able to implement the following in my twig template, which displays the custom route name I defined in my controller(s).

In index.html.twig

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

In my controller


    ...

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

        ...
     }

The result prints out "article_list" to the desired page in my browser.

klewis
  • 7,459
  • 15
  • 58
  • 102
-2

if you want to get route name in your controller than you have to inject the request (instead of getting from container due to Symfony UPGRADE and than call get('_route').

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

if you want to get route name in twig than you have to get it like

{{ app.request.attributes.get('_route') }}
Vazgen Manukyan
  • 1,410
  • 1
  • 12
  • 17
  • 1
    It is not recommended to use ```$request->get()``` directly because it's slow: https://github.com/symfony/http-foundation/blob/2.8/Request.php#L712 – ricko zoe Nov 19 '16 at 03:16