Wie erhalte ich die aktuelle Route in Symfony 2?


224

Wie erhalte ich die aktuelle Route in Symfony 2?

Zum Beispiel routing.yml:

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

Wie kann ich diesen somePageWert erhalten?

Antworten:


323

Von etwas, das ContainerAware ist (wie ein Controller):

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

2
@got eine switchwation für Sie überprüfen meta.stackexchange.com/questions/155258/…
NullPoiиteя

37
github.com/symfony/symfony/issues/854 request.attributes.get ('_ route') ist nicht zuverlässig, da es nur zu Debug-Zwecken dient (symfony dev sagte) und nicht funktioniert, wenn die Anfrage weitergeleitet wird ... siehe die Antwort von Supernova die dokumentiert und ausfallsicherer sind
luiges90

3
Der Grund dafür, dass dies nicht funktioniert, wenn etwas weitergeleitet wird, liegt in der Tatsache, dass Sie direkt an einen Controller weiterleiten, nicht an eine Route. Daher weiß Symfony nicht, für welche Route das ist. Normalerweise haben Sie eine Route zu einem Controller, daher kann es seltsam erscheinen, dass dies nichts anderes als "_internal" melden kann. Es ist jedoch möglich, Allzweck-Controller zu erstellen, die mehr als einer Routendefinition zugeordnet werden. Wenn Sie all dies betrachten, denke ich, dass dieses "Gotcha" sinnvoller ist.
jzimmerman2011

@ tuxedo25 Denken Sie an die Verwendung von RequestStack: symfony.com/blog/new-in-symfony-2-4-the-request-stack
mYkon

2
$ request-> get ('_ route'); ist langsam ! $ request-> Attribute-> get ('_ route'); ist besser, wenn Sie nicht die Flexibilität brauchen
Tom Tom

190

Mit Zweig: {{ app.request.attributes.get('_route') }}


8
Danke dir! <body class="{{ app.request.get('_route') | replace({'_' : '-'}) }}">
Salman von Abbas

10
github.com/symfony/symfony/issues/854 request.attributes.get ('_ route') ist nicht zuverlässig, da es nur zu Debug-Zwecken dient (symfony dev sagte) und nicht funktioniert, wenn die Anfrage weitergeleitet wird ... siehe die Antwort von Supernova die dokumentiert und ausfallsicherer sind
luiges90

48

Ich denke, das ist der einfachste Weg, dies zu tun:

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

    .....

3
Können Sie weitere Erklärungen hinzufügen oder Beispielausgaben anzeigen, um zu verdeutlichen, wie das Problem dadurch gelöst wird?
Charlie


1
@Charlie Es ist eine vordefinierte Variable, die Ihnen den übereinstimmenden Routennamen gibt
Supernova

2
Dies ist definitiv die beste Antwort auf die ursprüngliche Frage. Als Randnotiz: Es funktioniert jedoch nicht bei {% render "SomeBundle:SomeController:someAction" %}Unteranforderungen wie , bei denen Sie wieder den Wert '_internal' erhalten.
Netmikey

2
Schade ist, dass dies nur in der ursprünglichen Aktion funktioniert, für jede andere Funktion muss es weitergeleitet werden.
Darek Wędrychowski

27

Symfony 2.0-2.1
Verwenden Sie Folgendes :

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

Das wird dir nicht geben _internal.

Update für Symfony 2.2+: Dies funktioniert nicht ab Symfony 2.2+. Ich habe einen Fehler geöffnet und die Antwort war "by design". Wenn Sie die Route in einer Unteraktion erhalten möchten, müssen Sie sie als Argument übergeben

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

Und dein Controller:

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

github.com/symfony/symfony/issues/854 Ich bin mir nicht sicher, $route['_route']scheint problematisch zu sein, spricht aber möglicherweise nicht über Symfony-Entwickler. Das Kochbuch nicht erwähnen , _routeder $router->match()Ausgang ..
luiges90

Ich stimme @ luiges90 voll und ganz zu. Das PHPDoc von $router->match()sagt "@return array Ein Array von Parametern", was sehr intern zu sein scheint . Ich möchte mich nicht darauf verlassen, aber im Moment scheint es die einzig praktikable Lösung zu sein, wenn es um Unteranfragen geht.
Netmikey

19

Es gibt keine Lösung, die für alle Anwendungsfälle geeignet ist. Wenn Sie die Methode $ request-> get ('_ route') oder deren Varianten verwenden, wird in Fällen, in denen die Weiterleitung stattgefunden hat, '_internal' zurückgegeben .

Wenn Sie eine Lösung benötigen, die auch mit der Weiterleitung funktioniert, müssen Sie den neuen RequestStack-Dienst verwenden, der in Version 2.4 verfügbar ist. Dadurch wird jedoch die ESI-Unterstützung unterbrochen :

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

Sie können daraus eine Zweigerweiterung erstellen, wenn Sie diese in Vorlagen benötigen.


Also… wie funktioniert Ihre Lösung nicht für alle Anwendungsfälle genau?
Greg0ire

11

_routeist nicht der richtige Weg und war es auch nie . Laut Fabien, der Symfony erstellt hat, war es immer für Debugging-Zwecke gedacht . Es ist unzuverlässig, da es nicht mit Dingen wie Weiterleitung und anderen direkten Aufrufen an Controller wie partielles Rendern funktioniert.

Sie müssen den Namen Ihrer Route als Parameter in Ihren Controller einfügen. Weitere Informationen finden Sie im Dokument hier

Verwenden $request->get('');Sie diese Option $request->attributes->get('_route');in diesem Fall auch niemals, wenn Sie nicht die Flexibilität benötigen, die viel langsamer ist als die Verwendung von get für die von Ihnen benötigte Eigenschaftstasche (Attribute, Abfrage oder Anforderung) .


4
Ok, Sie schlagen grundsätzlich vor, allen Routen in diesen Dateien zusätzliche Informationen hinzuzufügen, anstatt den Routennamen zu erhalten. …
Charaf

1
Ja, besonders wenn Sie in der Lage sein müssen, den Controller später selbst aufzurufen (vorwärts, teilweises Rendern usw.). Die Übergabe des Namens als Parameter ist hier der einzige Weg, da Sie darin überhaupt keine Route aufrufen Fall. Was _route betrifft, das für Debug-Zwecke gedacht ist, nehmen Sie es nicht auf mich ^^ '
Tom Tom

7
$request->attributes->get('_route');

Sie können den Routennamen vom Anforderungsobjekt aus dem Controller abrufen.


4

Alles was ich davon bekomme ist _internal

Ich erhalte den $this->getRequest()->get('_route'). Routennamen aus einem Controller mit sogar dem Code tuxedo25, der die Rückgabe vorschlägt_internal

Dieser Code wird in einer so genannten "Komponente" in Symfony 1.X ausgeführt. Nicht der Controller einer Seite, sondern Teil einer Seite, die etwas Logik benötigt.

Der entsprechende Code in Symfony 1.X lautet: sfContext::getInstance()->getRouting()->getCurrentRouteName();


2
Hat es selbst gelöst. In einer Ansicht:$view['request']->getParameter('_route');
Alexismorin

5
Dies liegt daran, dass Sie {% render... %}Anrufe mit verwenden standalone=true. Wenn das Caching (AppCache.php oder Lack mit ESI) aktiviert ist, werden die Standalone-Ansichten mit einer separaten HTTP-Anforderung (hier kommt die Route _internalins Spiel) angefordert, damit sie unabhängig zwischengespeichert werden können.
Martin Schuhfuß

2

Mit Symfony 3.3 habe ich diese Methode verwendet und funktioniert einwandfrei.

Ich habe 4 Routen wie

admin_category_index, admin_category_detail, admin_category_create, admin_category_update

Und nur eine Zeile bildet eine aktive Klasse für alle Routen.

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

1

So ermitteln Sie die aktuelle Route anhand der URL (zuverlässiger bei Weiterleitungen):

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

Mit Symfony 4.2.7 kann ich Folgendes in meine Zweigvorlage implementieren, in der der benutzerdefinierte Routenname angezeigt wird, den ich in meinen Controllern definiert habe.

In index.html.twig

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

In meinem Controller


    ...

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

        ...
     }

Das Ergebnis druckt "article_list" auf die gewünschte Seite in meinem Browser.


0

Für alle, die eine aktuelle Route für Symfony 3 benötigen, verwende ich diese

<?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
Dies wird nicht den Namen der behandelten Route zurückgeben
Nico Haase

@NicoHaase Es ist keine Raketenwissenschaft, Sie haben bereits das Anforderungsobjekt
Aderemi Dayo

-2

Wenn Sie den Routennamen in Ihrem Controller abrufen möchten, müssen Sie die Anforderung einfügen (anstatt aufgrund von Symfony UPGRADE aus dem Container zu gelangen und dann get ('_ route') aufzurufen.

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

Wenn Sie den Routennamen in einem Zweig erhalten möchten, müssen Sie ihn wie folgt erhalten

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

1
Es wird nicht empfohlen, $request->get()direkt zu verwenden, da es langsam ist: github.com/symfony/http-foundation/blob/2.8/Request.php#L712
Ricko Zoe
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.