Làm cách nào để có được tuyến đường hiện tại trong Symfony 2?


224

Làm cách nào để có tuyến đường hiện tại trong Symfony 2?

Ví dụ routing.yml:

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

Làm thế nào tôi có thể nhận được somePagegiá trị này ?

Câu trả lời:


323

Từ thứ gì đó là ContainerAware (như bộ điều khiển):

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

2
@got một chuyển đổi cho bạn kiểm tra meta.stackexchange.com/questions/155258/NH
NullPoiиteя

37
github.com/symfony/symfony/issues/854 request.attribut.get ('_ tuyến') không đáng tin cậy vì nó chỉ dành cho mục đích gỡ lỗi (symfony dev nói) và không hoạt động nếu yêu cầu được chuyển tiếp ... xem câu trả lời của siêu tân tinh được ghi lại và không an toàn hơn
luiges90

3
Lý do cho việc này không hoạt động khi một cái gì đó được chuyển tiếp là do thực tế là bạn chuyển tiếp trực tiếp đến bộ điều khiển, không phải là một tuyến đường. Như vậy, Symfony không biết đó là tuyến đường nào. Thông thường, bạn có một tuyến đến một bộ điều khiển, do đó có vẻ lạ khi điều này không thể báo cáo bất cứ điều gì ngoài "_iternal", tuy nhiên, có thể tạo các bộ điều khiển đa năng có liên quan đến nhiều hơn một định nghĩa tuyến. Khi bạn xem xét tất cả những điều này, tôi nghĩ rằng "gotcha" này có ý nghĩa hơn.
jzimmerman2011

@ tuxedo25 Hãy suy nghĩ về việc sử dụng RequestStack: symfony.com/blog/new-in-symfony-2-4-the-request-stack
mYkon

2
$ request-> get ('_ tuyến'); chậm rồi $ request-> thuộc tính-> get ('_ tuyến'); sẽ tốt hơn nếu bạn không cần sự linh hoạt
Tom Tom

190

Với Twig: {{ app.request.attributes.get('_route') }}


8
Cảm ơn bạn! Đang sử dụng <body class="{{ app.request.get('_route') | replace({'_' : '-'}) }}">để áp dụng css dành riêng cho trang :)
Salman von Abbas

10
github.com/symfony/symfony/issues/854 request.attribut.get ('_ tuyến') không đáng tin cậy vì nó chỉ dành cho mục đích gỡ lỗi (symfony dev nói) và không hoạt động nếu yêu cầu được chuyển tiếp ... xem câu trả lời của siêu tân tinh được ghi lại và không an toàn hơn
luiges90

48

Tôi nghĩ rằng đây là cách dễ nhất để làm điều này:

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

    .....

3
Bạn có thể thêm giải thích hoặc hiển thị đầu ra mẫu để làm rõ cách giải quyết vấn đề này không?
Charlie


1
@Charlie Đó là một biến được xác định trước cung cấp cho bạn "tên" tuyến phù hợp
siêu tân tinh

2
Đây chắc chắn là câu trả lời tốt nhất cho câu hỏi ban đầu. Như một lưu ý phụ: tuy nhiên, nó không hoạt động với các yêu cầu phụ như {% render "SomeBundle:SomeController:someAction" %}, nơi bạn sẽ nhận được giá trị '_iternal' một lần nữa.
netmikey

2
Đáng tiếc là điều này chỉ hoạt động trong Hành động ban đầu, đối với bất kỳ chức năng nào khác, nó phải được chuyển tiếp.
Darek Wędrychowski

27

Symfony 2.0-2.1
Sử dụng điều này:

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

Điều đó sẽ không cung cấp cho bạn _internal.

Cập nhật cho Symfony 2.2+: Điều này không hoạt động khi bắt đầu Symfony 2.2+. Tôi đã mở một lỗi và câu trả lời là "theo thiết kế". Nếu bạn muốn có được tuyến đường trong một hành động phụ, bạn phải chuyển nó thành một đối số

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

Và bộ điều khiển của bạn:

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

github.com/symfony/symfony/issues/854 Tôi không chắc chắn về điều này, $route['_route']có vẻ có vấn đề nhưng có thể không phải là symfony dev nói về. Các sách dạy nấu ăn không đề cập về _routecác $router->match()đầu ra ..
luiges90

Tôi hoàn toàn đồng ý với @ luiges90. PHPDoc $router->match()nói "@return mảng Một mảng các tham số" có vẻ rất nội bộ. Tôi không muốn dựa vào nó, nhưng ngay bây giờ, nó dường như là giải pháp khả thi duy nhất khi xử lý các yêu cầu phụ.
netmikey

19

Không có giải pháp nào hoạt động cho tất cả các trường hợp sử dụng. Nếu bạn sử dụng phương thức $ request-> get ('_ route') hoặc các biến thể của nó, nó sẽ trả về '_iternal' cho các trường hợp diễn ra chuyển tiếp.

Nếu bạn cần một giải pháp hoạt động ngay cả với chuyển tiếp, bạn phải sử dụng dịch vụ RequestStack mới, đã có trong 2.4, nhưng điều này sẽ phá vỡ hỗ trợ ESI :

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

Bạn có thể tạo một phần mở rộng twig ra khỏi điều này nếu bạn cần nó trong các mẫu.


Vì vậy, làm thế nào giải pháp của bạn không hoạt động chính xác cho tất cả các trường hợp sử dụng?
greg0ire

11

_routekhông phải là cách để đi và không bao giờ được . Nó luôn có ý nghĩa cho mục đích gỡ lỗi theo Fabien, người đã tạo ra Symfony. Nó không đáng tin cậy vì nó sẽ không hoạt động với những thứ như chuyển tiếp và các cuộc gọi trực tiếp khác đến bộ điều khiển như kết xuất một phần.

Bạn cần thêm tên tuyến đường của mình làm tham số trong bộ điều khiển của mình, xem tài liệu ở đây

Ngoài ra, vui lòng không bao giờ sử dụng $request->get('');nếu bạn không cần sự linh hoạt, nó chậm hơn so với việc sử dụng get trên túi thuộc tính cụ thể mà bạn cần (thuộc tính, truy vấn hoặc yêu cầu) vì vậy $request->attributes->get('_route');trong trường hợp này.


4
Ok, về cơ bản, bạn đề nghị thêm thông tin bổ sung cho mọi tuyến đường trong tệp này thay vì lấy tên tuyến đường? Tiết
Charaf

1
Đúng, đặc biệt là nếu bạn cần có khả năng gọi chính bộ điều khiển sau đó xuống dòng (chuyển tiếp, kết xuất một phần, v.v ...) truyền tên dưới dạng tham số là cách duy nhất ở đây vì bạn hoàn toàn không gọi một tuyến đường trong đó trường hợp Đối với _route có nghĩa là cho mục đích gỡ lỗi, đừng lấy nó ra cho tôi ^^ '
Tom Tom

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

Bạn có thể lấy tên tuyến từ đối tượng yêu cầu từ trong bộ điều khiển.


4

Tất cả tôi nhận được từ đó là _internal

Tôi nhận được tên tuyến đường từ bên trong bộ điều khiển với $this->getRequest()->get('_route'). Ngay cả mã tuxedo25 được đề xuất trả về_internal

Mã này được thực thi trong cái được gọi là 'Thành phần' trong Symfony 1.X; Không phải bộ điều khiển của trang mà là một phần của trang cần logic.

Mã tương đương trong Symfony 1.X là: sfContext::getInstance()->getRouting()->getCurrentRouteName();


2
Tự mình giải quyết nó. Theo quan điểm:$view['request']->getParameter('_route');
alexismorin

5
điều này là do bạn đang sử dụng {% render... %}các cuộc gọi với standalone=true. Với bộ nhớ đệm (AppCache.php hoặc véc ni có ESI) được bật, điều này sẽ khiến các chế độ xem độc lập được yêu cầu với Yêu cầu HTTP riêng biệt (đây là nơi tuyến đường _internalđi vào hoạt động) để ro có thể được lưu trữ độc lập.
Martin Schuhfuß

2

Với Symfony 3.3, tôi đã sử dụng phương pháp này và hoạt động tốt.

Tôi có 4 tuyến đường như

admin_carget_index, admin_carget_detail, admin_carget_create, admin_carget_update

Và chỉ một dòng tạo ra một lớp hoạt động cho tất cả các tuyến.

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

1

Để có được tuyến đường hiện tại dựa trên URL (đáng tin cậy hơn trong trường hợp chuyển tiếp):

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

Với Symfony 4.2.7, tôi có thể triển khai các mục sau trong mẫu twig của mình, hiển thị tên tuyến tùy chỉnh mà tôi đã xác định trong (các) bộ điều khiển của mình.

Trong index.html.twig

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

Trong bộ điều khiển của tôi


    ...

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

        ...
     }

Kết quả in ra "article_list" đến trang mong muốn trong trình duyệt của tôi.


0

Đối với bất kỳ ai cần tuyến đường hiện tại cho Symfony 3, đây là những gì tôi sử dụng

<?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
Điều này sẽ không trả lại tên của tuyến đường được xử lý
Nico Haase

@NicoHaase Đây không phải là khoa học tên lửa, bạn đã có đối tượng yêu cầu
Aderemi Dayo

-2

nếu bạn muốn nhận tên tuyến trong bộ điều khiển của mình hơn bạn phải thực hiện yêu cầu (thay vì nhận từ container do Symfony UPGRADE và hơn gọi get ('_ route').

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

nếu bạn muốn có được tên tuyến đường trong twig hơn bạn phải có được nó như thế nào

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

1
Không nên sử dụng $request->get()trực tiếp vì nó chậm: github.com/symfony/http-foundation/blob/2.8/Request.php#L712
ricko zoe
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.