Come ottenere il percorso corrente in Symfony 2?


224

Come posso ottenere il percorso corrente in Symfony 2?

Ad esempio routing.yml:

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

Come posso ottenere questo somePagevalore?

Risposte:


323

Da qualcosa che è ContainerAware (come un controller):

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

2
@gai una commutazione per controllare meta.stackexchange.com/questions/155258/…
NullPoiиteя

37
github.com/symfony/symfony/issues/854 request.attributes.get ('_ route') non è affidabile perché è solo a scopo di debug (ha detto dev symfony) e non funziona se la richiesta viene inoltrata ... vedi la risposta della supernova che sono documentati e sono più sicuri
luiges90

3
Il motivo per cui questo non funziona quando qualcosa viene inoltrato è dovuto al fatto che si inoltra direttamente a un controller, non a un percorso. Pertanto, Symfony non sa quale sia la rotta. In genere, hai una route verso un controller, quindi può sembrare strano che questo non possa riportare nulla oltre a "_internal", tuttavia, è possibile creare controller per scopi generici associati a più di una definizione di route. Quando consideri tutto ciò, penso che questo "gotcha" abbia più senso.
jzimmerman2011,

@ tuxedo25 Pensa all'utilizzo di RequestStack: symfony.com/blog/new-in-symfony-2-4-the-request-stack
mYkon

2
$ request-> get ( '_ route'); è lento ! $ request-> attributes-> get ( '_ route'); è meglio se non hai bisogno della flessibilità
Tom Tom

190

Con ramoscello: {{ app.request.attributes.get('_route') }}


8
Grazie! Sto usando <body class="{{ app.request.get('_route') | replace({'_' : '-'}) }}">per applicare css specifici per pagina :)
Salman von Abbas

10
github.com/symfony/symfony/issues/854 request.attributes.get ('_ route') non è affidabile perché è solo a scopo di debug (ha detto dev symfony) e non funziona se la richiesta viene inoltrata ... vedi la risposta della supernova che sono documentati e sono più sicuri
luiges90

48

Penso che questo sia il modo più semplice per farlo:

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

    .....

3
Potete aggiungere ulteriori spiegazioni o mostrare un output di esempio per chiarire come questo risolve il problema?
Charlie,


1
@Charlie È una variabile predefinita che ti dà il percorso corrispondente "name"
supernova

2
Questa è sicuramente la migliore risposta alla domanda originale. Come nota a margine: non funziona, tuttavia, con richieste secondarie come {% render "SomeBundle:SomeController:someAction" %}, dove otterrai di nuovo il valore '_internal'.
netmikey

2
È un peccato che questo funzioni solo nell'azione originale, per ogni altra funzione che deve essere inoltrata.
Darek Wędrychowski

27

Symfony 2.0-2.1
Usa questo:

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

Quello non ti darà _internal.

Aggiornamento per Symfony 2.2+: questo non funziona a partire da Symfony 2.2+. Ho aperto un bug e la risposta è stata "di progettazione". Se desideri ottenere il percorso in un'azione secondaria, devi passarlo come argomento

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

E il tuo controller:

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

github.com/symfony/symfony/issues/854 Non ne sono sicuro, $route['_route']sembra problematico ma potrebbe non essere lo sviluppatore di symfony di cui parla. Il libro di cucina non fa menzione su _routedi $router->match()uscita ..
luiges90

Sono pienamente d'accordo con @ luiges90. Il PHPDoc di $router->match()dice "@return array Un array di parametri" che sembra molto interno. Non voglio fare affidamento su di esso, ma in questo momento, sembra essere l'unica soluzione praticabile quando si trattano richieste secondarie.
netmikey

19

Non esiste una soluzione che funzioni per tutti i casi d'uso. Se usi il metodo $ request-> get ('_ route'), o le sue varianti, restituirà '_internal' per i casi in cui ha avuto luogo l'inoltro.

Se hai bisogno di una soluzione che funzioni anche con l'inoltro, devi utilizzare il nuovo servizio RequestStack, arrivato in 2.4, ma questo interromperà il supporto ESI :

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

Puoi creare un'estensione ramoscello se ne hai bisogno nei modelli.


Quindi ... come funziona esattamente la tua soluzione per tutti i casi d'uso?
greg0ire,

11

_routenon è la strada da percorrere e non lo è mai stata . È stato sempre pensato per scopi di debug secondo Fabien che ha creato Symfony. Non è affidabile in quanto non funzionerà con cose come l'inoltro e altre chiamate dirette ai controller come il rendering parziale.

Devi inserire il nome del percorso come parametro nel controller, consulta il documento qui

Inoltre, ti preghiamo di non utilizzare mai $request->get('');se non hai bisogno della flessibilità, è molto più lento rispetto all'uso di ottenere la borsa di proprietà specifica di cui hai bisogno (attributi, query o richiesta), quindi $request->attributes->get('_route');in questo caso.


4
Ok, in pratica suggerisci di aggiungere ulteriori informazioni a tutte le rotte in questo file invece di ottenere il nome della rotta? ...
Charaf,

1
Sì, specialmente se devi essere in grado di chiamare il controller stesso in un secondo momento lungo la linea (forward, rendering parziale, ecc ...) passando il nome come parametro è l'unico modo qui perché non stai chiamando affatto una route in quel Astuccio. Per quanto riguarda _route inteso per scopi di debug, non prendermene conto ^^ '
Tom Tom,

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

È possibile ottenere il nome della rotta dall'oggetto richiesta all'interno del controller.


4

Tutto ciò che sto ottenendo è _internal

Ricevo il nome della rotta da un controller con $this->getRequest()->get('_route'). Anche il codice tuxedo25 ha suggerito i ritorni_internal

Questo codice viene eseguito in quello che è stato chiamato 'Component' in Symfony 1.X; Non un controller di pagina ma parte di una pagina che necessita di logica.

Il codice equivalente in Symfony 1.X è: sfContext::getInstance()->getRouting()->getCurrentRouteName();


2
Risolto da solo. In una vista:$view['request']->getParameter('_route');
alexismorin,

5
questo perché stai usando le {% render... %}chiamate con standalone=true. Con la memorizzazione nella cache (AppCache.php o vernice con ESI) abilitata, le viste autonome verranno richieste con una richiesta HTTP separata (qui _internalentra in gioco il percorso ) per poter essere memorizzate nella cache in modo indipendente.
Martin Schuhfuß,

2

Con Symfony 3.3, ho usato questo metodo e ho lavorato bene.

Ho 4 percorsi come

admin_category_index, admin_category_detail, admin_category_create, admin_category_update

E solo una riga crea una classe attiva per tutte le rotte.

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

1

Per ottenere il percorso corrente in base all'URL (più affidabile in caso di forward):

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

Con Symfony 4.2.7, sono in grado di implementare quanto segue nel mio modello di ramoscello, che mostra il nome del percorso personalizzato che ho definito nei miei controller.

In index.html.twig

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

Nel mio controller


    ...

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

        ...
     }

Il risultato stampa "article_list" sulla pagina desiderata nel mio browser.


0

Per chiunque abbia bisogno del percorso corrente per Symfony 3, questo è quello che uso

<?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
Questo non restituirà il nome del percorso gestito
Nico Haase

@NicoHaase Non è scienza missilistica, stai già avendo l'oggetto richiesta
Aderemi Dayo

-2

se vuoi ottenere il nome della rotta nel tuo controller di quanto devi iniettare la richiesta (invece di ottenere dal contenitore a causa di UPFADE di Symfony e di chiamare get ('_ route').

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

se si desidera ottenere il nome del percorso in un ramoscello di quello che si deve ottenere come

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

1
Non è consigliabile utilizzare $request->get()direttamente perché è lento: github.com/symfony/http-foundation/blob/2.8/Request.php#L712
ricko zoe
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.