Como obter a rota atual no Symfony 2?

224

Como obtenho a rota atual no Symfony 2?

Por exemplo routing.yml:

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

Como posso obter esse somePagevalor?

IlyaDoroshin
fonte

Respostas:

323

De algo que é ContainerAware (como um controlador):

$request = $this->container->get('request');
$routeName = $request->get('_route');
tuxedo25
fonte
2
@got uma alternância para você verificar meta.stackexchange.com/questions/155258/…
NullPoiиteя
37
github.com/symfony/symfony/issues/854 request.attributes.get ('_ route') não é confiável porque é apenas para fins de depuração (symfony dev disse) e não funciona se a solicitação for encaminhada ... veja a resposta da supernova que estão documentadas e são mais à prova de falhas
luiges90
3
A razão para isso não funcionar quando algo é encaminhado se deve ao fato de você encaminhar diretamente para um controlador, não para uma rota. Como tal, o Symfony não sabe para que rota serve. Normalmente, você tem uma rota para um controlador, portanto, pode parecer estranho que isso não possa relatar nada além de "_internal"; no entanto, é possível criar controladores de uso geral que são associados a mais de uma definição de rota. Quando você considera tudo isso, acho que essa "pegadinha" faz mais sentido.
jzimmerman2011
@ tuxedo25 Pense em usar RequestStack: symfony.com/blog/new-in-symfony-2-4-the-request-stack #
mYkon
2
$ request-> get ('_ route'); é lento ! $ request-> attribute-> get ('_ route'); é melhor se você não precisar de flexibilidade #
Tom Tom
190

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

Matthieu
fonte
8
Obrigado! Estou usando <body class="{{ app.request.get('_route') | replace({'_' : '-'}) }}">para aplicar css específico da página :)
Salman von Abbas
10
github.com/symfony/symfony/issues/854 request.attributes.get ('_ route') não é confiável porque é apenas para fins de depuração (symfony dev disse) e não funciona se a solicitação for encaminhada ... veja a resposta da supernova que estão documentadas e são mais à prova de falhas
luiges90
48

Eu acho que essa é a maneira mais fácil de fazer isso:

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

    .....
Super Nova
fonte
3
Você pode adicionar mais explicações ou mostrar exemplos de saída para esclarecer como isso resolve o problema?
612 Charlie
1
@Charlie É uma variável predefinida que fornece a rota "nome" correspondente
supernova
2
Esta é definitivamente a melhor resposta para a pergunta original. Como uma observação lateral: no entanto, não funciona com sub-solicitações como {% render "SomeBundle:SomeController:someAction" %}, onde você obterá o valor '_internal' novamente.
Net13 #
2
Uma pena é que isso funcione apenas na Ação original, para qualquer outra função que precise ser encaminhada.
Darek Wędrychowski
27

Symfony 2.0-2.1
Use isto:

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

Aquele não vai te dar _internal.

Atualização para o Symfony 2.2+: Isso não está funcionando ao iniciar o Symfony 2.2+. Abri um bug e a resposta foi "por design". Se você deseja obter a rota em uma sub-ação, deve transmiti-la como argumento

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

E seu controlador:

public function menuAction($route) { ... }
jsgoupil
fonte
github.com/symfony/symfony/issues/854 Não tenho certeza disso, $route['_route']parece problemático, mas pode não ser o que o symfony dev fala. O livro de receitas não menciona cerca _routede $router->match()saída ..
luiges90
Concordo plenamente com @ luiges90. O PHPDoc $router->match()diz "@return array Uma matriz de parâmetros" que parece muito interna. Não quero confiar nisso, mas, no momento, parece ser a única solução viável ao lidar com sub-solicitações.
netmikey
19

Não há solução que funcione para todos os casos de uso. Se você usar o método $ request-> get ('_ route') ou suas variantes, ele retornará '_internal' para os casos em que o encaminhamento ocorreu.

Se você precisar de uma solução que funcione mesmo com o encaminhamento, precisará usar o novo serviço RequestStack, que chegou na 2.4, mas isso interromperá o suporte ESI :

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

Você pode fazer uma extensão de galho, se precisar nos modelos.

K. Norbert
fonte
Então ... como sua solução não funciona exatamente para todos os casos de uso?
greg0ire
11

_routenão é o caminho a percorrer e nunca foi . Sempre foi feito para fins de depuração, de acordo com Fabien, que criou o Symfony. Não é confiável, pois não funcionará com coisas como encaminhamento e outras chamadas diretas para controladores, como renderização parcial.

Você precisa injetar o nome da sua rota como parâmetro no seu controlador, consulte o documento aqui

Além disso, nunca use $request->get('');se você não precisar da flexibilidade, pois é muito mais lento do que usar get no pacote de propriedades específico que você precisa (atributos, consulta ou solicitação), portanto $request->attributes->get('_route');, neste caso.

Tom Tom
fonte
4
Ok, você basicamente sugere adicionar informações extras a todas as rotas nesses arquivos, em vez de obter o nome da rota? ...
Charaf 22/02
1
Sim, especialmente se você precisar chamar o próprio controlador mais tarde na linha (encaminhamento, renderização parcial, etc ...), passar o nome como parâmetro é o único caminho aqui, porque você não está chamando uma rota nesse sentido. caso. Quanto _route sendo destinadas para fins de depuração não levá-lo para fora em mim ^^'
Tom Tom
7
$request->attributes->get('_route');

Você pode obter o nome da rota do objeto de solicitação de dentro do controlador.

Venkat Kotra
fonte
4

Tudo o que estou obtendo disso é _internal

Eu recebo o nome da rota de dentro de um controlador com $this->getRequest()->get('_route'). Até o código tuxedo25 sugerido retorna_internal

Esse código é executado no que foi chamado de 'Componente' no Symfony 1.X; Não é o controlador de uma página, mas parte de uma página que precisa de alguma lógica.

O código equivalente no Symfony 1.X é: sfContext::getInstance()->getRouting()->getCurrentRouteName();

alexismorin
fonte
2
Eu mesmo resolvi. Em vista:$view['request']->getParameter('_route');
alexismorin 17/10/11
5
isso é porque você está usando {% render... %}chamadas com standalone=true. Com o armazenamento em cache (AppCache.php ou verniz com ESI) ativado, isso fará com que as visualizações independentes sejam solicitadas com uma Solicitação HTTP separada (é aqui que a rota _internalentra em ação) para que seja armazenada em cache independentemente.
Martin Schuhfuß
2

Com o Symfony 3.3, eu usei esse método e funcionando bem.

Eu tenho 4 rotas como

admin_category_index, admin_category_detail, admin_category_create, admin_category_update

E apenas uma linha cria uma classe ativa para todas as rotas.

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

Para obter a rota atual com base no URL (mais confiável no caso de encaminhamentos):

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

Com o Symfony 4.2.7, sou capaz de implementar o seguinte no meu modelo de galho, que exibe o nome da rota personalizada que defini no (s) meu (s) controlador (es).

Em index.html.twig

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

No meu controlador


    ...

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

        ...
     }

O resultado imprime "article_list" na página desejada no meu navegador.

klewis
fonte
0

Para quem precisa de rota atual para o Symfony 3, é isso que eu 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
fonte
3
Isso não vai devolver o nome da rota tratado
Nico Haase
@NicoHaase Não é ciência de foguetes, você já está tendo o objeto de solicitação
Aderemi Dayo 24/02
-2

se você deseja obter o nome da rota no seu controlador, precisa injetar a solicitação (em vez de sair do contêiner devido ao Symfony UPGRADE e chamar a função get ('_ route').

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

se você deseja obter o nome da rota em galho do que você precisa

{{ app.request.attributes.get('_route') }}
Vazgen Manukyan
fonte
1
Não é recomendado usar $request->get()diretamente porque ele é lento: github.com/symfony/http-foundation/blob/2.8/Request.php#L712
ricko zoe