Jak uzyskać aktualną trasę w Symfony 2?

224

Jak uzyskać aktualną trasę w Symfony 2?

Na przykład routing.yml:

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

Jak mogę uzyskać tę somePagewartość?

IlyaDoroshin
źródło

Odpowiedzi:

323

Z czegoś, co jest ContainerAware (jak kontroler):

$request = $this->container->get('request');
$routeName = $request->get('_route');
tuxedo25
źródło
2
@gotowałam dla ciebie switchwation,
NullPoiиteя
37
github.com/symfony/symfony/issues/854 request.attributes.get ('_ route') nie jest wiarygodny, ponieważ służy wyłącznie do debugowania (powiedział symfony dev) i nie działa, jeśli żądanie zostanie przekazane ... zobacz odpowiedź supernowej które są udokumentowane i są bardziej bezpieczne w
razie
3
Przyczyną tego, że nie działa, gdy coś jest przesyłane, jest to, że przekazujesz bezpośrednio do kontrolera, a nie trasy. W związku z tym Symfony nie wie, do czego służy. Zazwyczaj masz jedną trasę do jednego kontrolera, więc może wydawać się dziwne, że nie może zgłaszać niczego oprócz „_internal”, jednak możliwe jest utworzenie kontrolerów ogólnego przeznaczenia, które zostaną skojarzone z więcej niż jedną definicją trasy. Biorąc pod uwagę to wszystko, myślę, że to „gotcha” ma sens.
jzimmerman2011
@ tuxedo25 Pomyśl o użyciu RequestStack: symfony.com/blog/new-in-symfony-2-4-the-request-stack
mYkon
2
$ request-> get ('_ route'); jest wolny ! $ request-> atrybuty-> get ('_ route'); jest lepiej, jeśli nie potrzebujesz elastyczności
Tom Tom
190

Z gałązką: {{ app.request.attributes.get('_route') }}

Matthieu
źródło
8
Dziękuję Ci! Używam <body class="{{ app.request.get('_route') | replace({'_' : '-'}) }}">do stosowania css specyficznych dla strony :)
Salman von Abbas
10
github.com/symfony/symfony/issues/854 request.attributes.get ('_ route') nie jest wiarygodny, ponieważ służy wyłącznie do debugowania (powiedział symfony dev) i nie działa, jeśli żądanie zostanie przekazane ... zobacz odpowiedź supernowej które są udokumentowane i są bardziej bezpieczne w
razie
48

Myślę, że to najłatwiejszy sposób:

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

    .....
supernowa
źródło
3
Czy możesz dodać więcej wyjaśnień lub pokazać przykładowe wyniki, aby wyjaśnić, jak to rozwiązuje problem?
Charlie,
1
@Charlie Jest to predefiniowana zmienna, która daje dopasowaną trasę „nazwa”
supernowa
2
To zdecydowanie najlepsza odpowiedź na pierwotne pytanie. Na marginesie: nie działa to jednak w przypadku żądań podrzędnych, takich jak {% render "SomeBundle:SomeController:someAction" %}, gdzie ponownie otrzymasz wartość „_internal”.
netmikey
2
Szkoda, że ​​działa to tylko w oryginalnej Akcji, dla każdej innej funkcji trzeba ją przekazać.
Darek Wędrychowski
27

Symfony 2.0-2.1
Użyj tego:

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

Tego ci nie da _internal.

Aktualizacja dla Symfony 2.2+: To nie działa, uruchamiając Symfony 2.2+. Otworzyłem błąd i odpowiedź brzmiała „zgodnie z projektem”. Jeśli chcesz uzyskać trasę w podakcji, musisz podać ją jako argument

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

A twój kontroler:

public function menuAction($route) { ... }
jsgoupil
źródło
github.com/symfony/symfony/issues/854 Nie jestem tego pewien, $route['_route']wydaje się problematyczny, ale może nie być gadaniem deweloperów symfony. The Cookbook nie wspominając o _routeod $router->match()wyjścia ..
luiges90
W pełni zgadzam się z @ luiges90. PHPDoc $router->match()mówi „@return array Tablica parametrów”, co wydaje się bardzo wewnętrzne. Nie chcę na tym polegać, ale w tej chwili wydaje się, że jest to jedyne realne rozwiązanie w przypadku pod-żądań.
netmikey
19

Nie ma rozwiązania, które działałoby we wszystkich przypadkach użycia. Jeśli użyjesz metody $ request-> get ('_ route') lub jej wariantów, zwróci ona „_internal” w przypadkach, w których miało miejsce przekazywanie.

Jeśli potrzebujesz rozwiązania, które działa nawet przy przesyłaniu dalej, musisz skorzystać z nowej usługi RequestStack, która została dostarczona w wersji 2.4, ale spowoduje to przerwanie obsługi ESI :

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

Możesz zrobić z niego rozszerzenie gałązki, jeśli potrzebujesz go w szablonach.

K. Norbert
źródło
Więc… jak twoje rozwiązanie nie działa dokładnie dla wszystkich przypadków użycia?
greg0ire
11

_routeto nie jest droga i nigdy nie było . Zawsze był przeznaczony do debugowania według Fabiena, który stworzył Symfony. Jest zawodny, ponieważ nie będzie działał z takimi rzeczami, jak przekazywanie i inne bezpośrednie połączenia do kontrolerów, takie jak częściowe renderowanie.

Musisz wprowadzić nazwę trasy jako parametr w kontrolerze, zobacz dokument tutaj

Ponadto, nigdy nie używaj, $request->get('');jeśli nie potrzebujesz elastyczności, ponieważ jest ona znacznie wolniejsza niż korzystanie z konkretnej torby właściwości, której potrzebujesz (atrybuty, zapytanie lub żądanie), więc $request->attributes->get('_route');w tym przypadku.

Tom Tom
źródło
4
Ok, zasadniczo sugerujesz dodanie dodatkowych informacji do każdej trasy w tych plikach zamiast uzyskiwania nazwy trasy? …
Charaf,
1
Tak, zwłaszcza jeśli musisz móc później wywołać sam kontroler w dół linii (do przodu, częściowe renderowanie itp.). Przekazywanie nazwy jako parametru jest tutaj jedynym sposobem, ponieważ w ogóle nie wywołujesz trasy walizka. Jeśli chodzi o _route przeznaczone do celów debugowania, nie wyciągaj go ze mnie ^^ '
Tom Tom
7
$request->attributes->get('_route');

Nazwę trasy można uzyskać z obiektu żądania z poziomu kontrolera.

Venkat Kotra
źródło
4

Wszystko, co z tego czerpię, to _internal

Dostaję nazwę trasy z wnętrza kontrolera, $this->getRequest()->get('_route'). nawet kod tuxedo25 sugeruje zwroty_internal

Ten kod jest wykonywany w tak zwanym „komponencie” w Symfony 1.X; Nie kontroler strony, ale część strony, która wymaga pewnej logiki.

Odpowiednikiem kodu w Symfony 1.X jest: sfContext::getInstance()->getRouting()->getCurrentRouteName();

alexismorin
źródło
2
Sam to rozwiązałem. W widoku:$view['request']->getParameter('_route');
aleksjonorina
5
dzieje się tak, ponieważ używasz {% render... %}połączeń z standalone=true. Przy włączonym buforowaniu (AppCache.php lub lakier z ESI) spowoduje to żądanie niezależnych widoków z oddzielnym żądaniem HTTP (tutaj rozpoczyna się trasa _internal), aby ro można było niezależnie buforować.
Martin Schuhfuß
2

W Symfony 3.3 zastosowałem tę metodę i działałem dobrze.

Mam 4 trasy jak

admin_category_index, admin_category_detail, admin_category_create, admin_category_update

I tylko jedna linia tworzy aktywną klasę dla wszystkich tras.

<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
źródło
1

Aby uzyskać bieżącą trasę na podstawie adresu URL (bardziej niezawodne w przypadku przekazywania dalej):

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
źródło
0

W Symfony 4.2.7 jestem w stanie zaimplementować następujące elementy w moim szablonie gałązki, który wyświetla niestandardową nazwę trasy zdefiniowaną w moich kontrolerach.

W index.html.twig

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

W moim kontrolerze


    ...

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

        ...
     }

Wynik wypisuje „article_list” na wybranej stronie w mojej przeglądarce.

Klewis
źródło
0

Dla każdego, kto potrzebuje aktualnej trasy do Symfony 3, tego właśnie używam

<?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
źródło
3
To nie zwróci nazwy obsługiwanej trasy
Nico Haase
@NicoHaase To nie jest nauka o rakietach, już masz obiekt zapytania
Aderemi Dayo
-2

jeśli chcesz uzyskać nazwę trasy w swoim kontrolerze, musisz wstrzyknąć żądanie (zamiast pobierać z kontenera ze względu na Symfony UPGRADE i niż wywołać get ('_ route').

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

jeśli chcesz uzyskać nazwę trasy w gałązce, niż musisz ją uzyskać

{{ app.request.attributes.get('_route') }}
Vazgen Manukyan
źródło
1
Nie zaleca się używania $request->get()bezpośrednio, ponieważ jest wolny: github.com/symfony/http-foundation/blob/2.8/Request.php#L712
ricko zoe