Как узнать текущий маршрут в Symfony 2?

171

Как получить текущий маршрут в Symfony 2?

Например, routing.yml:

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

Как я могу получить это значение somePage?

Теги:
routing
symfony-routing

12 ответов

267
Лучший ответ

Из чего-то, что является ContainerAware (например, контроллер):

$request = $this->container->get('request');
$routeName = $request->get('_route');
  • 2
    @ Получите переломный момент для вас, проверьте meta.stackexchange.com/questions/155258/…
  • 33
    github.com/symfony/symfony/issues/854 request.attributes.get ('_ route') ненадежен, поскольку он предназначен только для целей отладки (сказал symfony dev) и не работает, если запрос перенаправлен ... см. ответ суперновы которые задокументированы и более надежны
Показать ещё 4 комментария
171

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

  • 8
    Спасибо! Я использую <body class="{{ app.request.get('_route') | replace({'_' : '-'}) }}"> для применения css для конкретной страницы :)
  • 10
    github.com/symfony/symfony/issues/854 request.attributes.get ('_ route') ненадежен, поскольку он предназначен только для целей отладки (сказал symfony dev) и не работает, если запрос перенаправлен ... см. ответ суперновы которые задокументированы и более надежны
45

Я думаю, что это самый простой способ сделать это:

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

    .....
  • 2
    Можете ли вы добавить больше объяснений или показать пример выходных данных, чтобы уточнить, как это решает проблему?
  • 7
    @charlie symfony.com/doc/master/book/…
Показать ещё 4 комментария
24

Symfony 2.0-2.1
Используйте это:

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

Это не даст вам _internal.

Обновление для Symfony 2.2 +: Это не работает, начиная с Symfony 2.2+. Я открыл ошибку и ответ был "по дизайну" . Если вы хотите получить маршрут в под-действии, вы должны передать его в качестве аргумента

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

И ваш контроллер:

public function menuAction($route) { ... }
  • 0
    github.com/symfony/symfony/issues/854 Я не уверен в этом, $route['_route'] кажется проблематичным, но это может быть не то, о чем говорит symfony dev. В кулинарной книге не упоминается _route $router->match() .
  • 0
    Я полностью согласен с @ luiges90. В PHPDoc для $router->match() написано "@return array Массив параметров", который выглядит очень внутренним. Я не хочу на это полагаться, но сейчас, похоже, это единственное жизнеспособное решение при работе с подзапросами.
17

Нет решения, которое работает для всех случаев использования. Если вы используете метод $request- > get ('_ route') или его варианты, он вернет '_internal' для случаев, когда была выполнена пересылка.

Если вам нужно решение, которое работает даже с пересылкой, вам нужно использовать новую службу RequestStack, которая прибыла в 2.4, но это сломает Поддержка ESI:

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

Вы можете сделать расширение ветки из этого, если вам это нужно в шаблонах.

  • 0
    Итак ... как ваше решение не работает точно для всех вариантов использования?
  • 1
    Это нарушает ESI, но в остальном работает во всех случаях.
7

_route - это не путь и никогда не был. Он всегда был предназначен для целей отладки в соответствии с Фабиеном, который создал Symfony. Это ненадежно, поскольку оно не будет работать с такими вещами, как переадресация и другие прямые вызовы контроллерам, такие как частичный рендеринг.

Вам нужно ввести название маршрута в качестве параметра в вашем контроллере, посмотреть здесь документ

Кроме того, никогда не используйте $request->get('');, если вам не нужна гибкость, это медленнее, чем использование того, что вам нужно (атрибуты, запрос или запрос), поэтому $request->attributes->get('_route'); в этом случае.

  • 4
    Хорошо, вы в основном предлагаете добавить дополнительную информацию к каждому маршруту в этих файлах вместо того, чтобы получить название маршрута? ... Этот способ мышления и реагирования на борьбу людей является одной из причин, по которой все больше и больше людей ненавидят Symfony.
  • 1
    Да, особенно если вам нужно иметь возможность вызывать сам контроллер позже по линии (пересылка, частичный рендеринг и т. Д.), Передавая имя в качестве параметра, - единственный способ, поскольку вы вообще не вызываете маршрут в этом случае. дело. Что касается _route, предназначенного для целей отладки, не берите это на себя ^^ '
7
$request->attributes->get('_route');

Вы можете получить имя маршрута из объекта запроса из контроллера.

4

Все, что я получаю от этого   _internal

Я получаю имя маршрута внутри контроллера с помощью $this->getRequest()->get('_route'). Даже код tuxedo25 предложил вернуть _internal

Этот код выполняется в так называемом "компоненте" в Symfony 1.X; Не является страничным контроллером, а частью страницы, которая нуждается в некоторой логике.

Эквивалентный код в Symfony 1.X: sfContext::getInstance()->getRouting()->getCurrentRouteName();

  • 2
    Решил это сам. В представлении: $view['request']->getParameter('_route');
  • 5
    это потому, что вы используете {% render... %} вызовы с standalone=true . При включенном кэшировании (AppCache.php или varnish with ESI) это приведет к тому, что автономные представления будут запрашиваться с отдельным HTTP-запросом (именно здесь вступает в действие маршрут _internal ), чтобы обеспечить независимое кэширование.
2

С Symfony 3.3 я использовал этот метод и отлично работал.

У меня есть 4 маршрута, например

admin_category_index, admin_category_detail, admin_category_create, admin_category_update

И только одна строка делает активный класс для всех маршрутов.

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

Для тех, кому нужен текущий маршрут для Symfony 3, это то, что я использую

<?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
?>
  • 1
    Это не вернет название обработанного маршрута
0

Чтобы получить текущий маршрут на основе URL (более надежный в случае переадресации):

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;
}
-2

если вы хотите получить имя маршрута в своем контроллере, вместо того, чтобы вводить запрос (вместо получения из контейнера из-за Symfony UPGRADE и чем вызов get ('_ route').

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

если вы хотите получить имя маршрута в ветке, чем вы должны получить его как

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню