¿Cómo obtener la ruta actual en Symfony 2?

224

¿Cómo obtengo la ruta actual en Symfony 2?

Por ejemplo routing.yml:

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

¿Cómo puedo obtener este somePagevalor?

IlyaDoroshin
fuente

Respuestas:

323

De algo que es ContainerAware (como un controlador):

$request = $this->container->get('request');
$routeName = $request->get('_route');
esmoquin25
fuente
2
@ obtuve un interruptor para que revises meta.stackexchange.com/questions/155258/…
NullPoiиteя
37
github.com/symfony/symfony/issues/854 request.attributes.get ('_ route') no es confiable porque es solo para propósitos de depuración (dijo symfony dev) y no funciona si se reenvía la solicitud ... ver la respuesta de supernova que están documentados y son más a prueba de fallas
luiges90
3
La razón por la que esto no funciona cuando se reenvía algo se debe al hecho de que reenvía directamente a un controlador, no a una ruta. Como tal, Symfony no sabe para qué ruta es. Por lo general, tiene una ruta hacia un controlador, por lo que puede parecer extraño que esto no pueda informar nada más que "interno", sin embargo, es posible crear controladores de uso general que se asocian con más de una definición de ruta. Cuando consideras todo esto, creo que esta "trampa" tiene más sentido.
jzimmerman2011
@ tuxedo25 Piensa en usar RequestStack: symfony.com/blog/new-in-symfony-2-4-the-request-stack
mYkon
2
$ request-> get ('_ ruta'); es lento ! $ solicitud-> atributos-> get ('_ ruta'); es mejor si no necesita la flexibilidad
Tom Tom
190

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

Matthieu
fuente
8
¡Gracias! Estoy usando <body class="{{ app.request.get('_route') | replace({'_' : '-'}) }}">para aplicar CSS específico de la página :)
Salman von Abbas
10
github.com/symfony/symfony/issues/854 request.attributes.get ('_ route') no es confiable porque es solo para propósitos de depuración (dijo symfony dev) y no funciona si se reenvía la solicitud ... ver la respuesta de supernova que están documentados y son más a prueba de fallas
luiges90
48

Creo que esta es la forma más fácil de hacer esto:

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

    .....
supernova
fuente
3
¿Puede agregar más explicaciones o mostrar resultados de muestra para aclarar cómo esto resuelve el problema?
Charlie
1
@Charlie Es una variable predefinida que te da el "nombre" de la ruta coincidente
supernova
2
Esta es definitivamente la mejor respuesta a la pregunta original. Como nota al margen: no funciona, sin embargo, con solicitudes secundarias como {% render "SomeBundle:SomeController:someAction" %}, donde obtendrá el valor '_internal' nuevamente.
netmikey
2
Una lástima es que esto solo funciona en la Acción original, para cualquier otra función tiene que reenviarse.
Darek Wędrychowski
27

Symfony 2.0-2.1
Use esto:

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

Ese no te dará _internal.

Actualización para Symfony 2.2+: Esto no funciona a partir de Symfony 2.2+. Abrí un error y la respuesta fue "por diseño". Si desea obtener la ruta en una sub-acción, debe pasarla como argumento

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

Y tu controlador:

public function menuAction($route) { ... }
jsgoupil
fuente
github.com/symfony/symfony/issues/854 No estoy seguro de esto, $route['_route']parece problemático pero podría no ser de lo que habla el desarrollador de Symfony. El libro de cocina no menciona acerca _routede la $router->match()producción ..
luiges90
Estoy totalmente de acuerdo con @ luiges90. El PHPDoc de $router->match()dice "@return array Una matriz de parámetros" que parece muy interno. No quiero confiar en ello, pero en este momento, parece ser la única solución viable cuando se trata de solicitudes secundarias.
netmikey
19

No existe una solución que funcione para todos los casos de uso. Si utiliza el método $ request-> get ('_ route'), o sus variantes, devolverá '_internal' para los casos en que se realizó el reenvío.

Si necesita una solución que funcione incluso con el reenvío, debe usar el nuevo servicio RequestStack, que llegó en 2.4, pero esto interrumpirá el soporte de ESI :

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

Puede hacer una extensión de ramita de esto si lo necesita en plantillas.

K. Norbert
fuente
Entonces ... ¿cómo funciona su solución no para todos los casos de uso exactamente?
greg0ire
11

_routeNo es el camino a seguir y nunca fue . Siempre fue para fines de depuración de acuerdo con Fabien, quien creó Symfony. No es confiable ya que no funcionará con cosas como el reenvío y otras llamadas directas a los controladores como el renderizado parcial.

Debe inyectar el nombre de su ruta como parámetro en su controlador, consulte el documento aquí

Además, nunca lo use $request->get('');si no necesita la flexibilidad, es mucho más lento que usar get en la bolsa de propiedades específica que necesita (atributos, consulta o solicitud), así que $request->attributes->get('_route');en este caso.

Tom Tom
fuente
44
Ok, ¿básicamente sugieres agregar información adicional a todas las rutas en estos archivos en lugar de obtener el nombre de la ruta? ...
Charaf
1
Sí, especialmente si necesita poder llamar al controlador más adelante en la línea (reenvío, representación parcial, etc.), pasar el nombre como parámetro es la única forma aquí porque no está llamando a una ruta en absoluto en ese sentido caso. En cuanto a _route para propósitos de depuración, no me desquites conmigo ^^ '
Tom Tom
7
$request->attributes->get('_route');

Puede obtener el nombre de ruta del objeto de solicitud desde el controlador.

Venkat Kotra
fuente
4

Todo lo que obtengo de eso es _internal

Obtengo el nombre de la ruta desde dentro de un controlador con $this->getRequest()->get('_route'). Incluso el código tuxedo25 sugiere devoluciones_internal

Este código se ejecuta en lo que se llamó un 'Componente' en Symfony 1.X; No es el controlador de una página, sino parte de una página que necesita algo de lógica.

El código equivalente en Symfony 1.X es: sfContext::getInstance()->getRouting()->getCurrentRouteName();

alexismorin
fuente
2
Lo resolví yo mismo. En una vista:$view['request']->getParameter('_route');
alexismorin
55
Esto se debe a que está utilizando {% render... %}llamadas con standalone=true. Con el almacenamiento en caché (AppCache.php o barniz con ESI) habilitado, esto hará que las vistas independientes se soliciten con una solicitud HTTP separada (aquí es donde _internalentra en juego la ruta ) para que se pueda almacenar en caché de forma independiente.
Martin Schuhfuß
2

Con Symfony 3.3, he usado este método y funciona bien.

Tengo 4 rutas como

admin_category_index, admin_category_detail, admin_category_create, admin_category_update

Y solo una línea hace una clase activa para todas las rutas.

<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
fuente
1

Para obtener la ruta actual basada en la URL (más confiable en caso de reenvío):

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
fuente
0

Con Symfony 4.2.7, puedo implementar lo siguiente en mi plantilla de ramita, que muestra el nombre de ruta personalizado que definí en mi (s) controlador (es).

En index.html.twig

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

En mi controlador


    ...

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

        ...
     }

El resultado imprime "article_list" en la página deseada en mi navegador.

klewis
fuente
0

Para cualquiera que necesite una ruta actual para Symfony 3, esto es lo que 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.
?>
Aderemi Dayo
fuente
3
Esto no devolverá el nombre de la ruta manejada
Nico Haase
@NicoHaase No es ciencia espacial, ya tienes el objeto de solicitud
Aderemi Dayo
-2

si desea obtener el nombre de la ruta en su controlador, entonces tiene que inyectar la solicitud (en lugar de obtener del contenedor debido a la ACTUALIZACIÓN de Symfony y luego llamar a get ('_ route').

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

si desea obtener el nombre de la ruta en la rama, entonces debe obtenerlo como

{{ app.request.attributes.get('_route') }}
Vazgen Manukyan
fuente
1
No se recomienda usar $request->get()directamente porque es lento: github.com/symfony/http-foundation/blob/2.8/Request.php#L712
ricko zoe