จะรับเส้นทางปัจจุบันใน Symfony 2 ได้อย่างไร


224

ฉันจะรับเส้นทางปัจจุบันในSymfony 2 ได้อย่างไร

ตัวอย่างเช่นrouting.yml:

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

ฉันจะรับsomePageค่านี้ได้อย่างไร

คำตอบ:


323

จากสิ่งที่เป็น ContainerAware (เช่นตัวควบคุม):

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

2
@ ได้สวิตช์สำหรับคุณตรวจสอบmeta.stackexchange.com/questions/155258/ …
NullPoiиteя

37
github.com/symfony/symfony/issues/854 request.attributes.get ('_ route') ไม่น่าเชื่อถือเพราะมันมีวัตถุประสงค์เพื่อการแก้ปัญหาเท่านั้น (Symfony dev กล่าวว่า) และไม่ทำงานหากคำขอถูกส่งต่อ ... ดูคำตอบของซูเปอร์โนวา ซึ่งได้รับการบันทึกและมีความปลอดภัยมากกว่า
luiges90

3
เหตุผลนี้ไม่ทำงานเมื่อมีการส่งต่อบางสิ่งบางอย่างเกิดจากความจริงที่ว่าคุณส่งต่อไปยังตัวควบคุมโดยตรงไม่ใช่เส้นทาง ดังนั้น Symfony จึงไม่ทราบว่าต้องใช้เส้นทางใด โดยทั่วไปคุณมีหนึ่งเส้นทางไปยังตัวควบคุมหนึ่งดังนั้นมันอาจดูแปลกที่ว่าสิ่งนี้ไม่สามารถรายงานอะไรนอกเหนือจาก "_internal" อย่างไรก็ตามมันเป็นไปได้ที่จะสร้างตัวควบคุมวัตถุประสงค์ทั่วไปที่เชื่อมโยงกับนิยามเส้นทางมากกว่าหนึ่งรายการ เมื่อคุณพิจารณาทั้งหมดนี้ฉันคิดว่า "gotcha" นี้เหมาะสมกว่า
jzimmerman2011

@ tuxedo25 คิดเกี่ยวกับการใช้ RequestStack: symfony.com/blog/new-in-symfony-2-4-the-request-stack
mYkon

2
$ คำขอ> รับ ( '_ เส้นทาง'); ช้า! $ คำขอ> attributes-> รับ ( '_ เส้นทาง'); จะดีกว่าถ้าคุณไม่ต้องการความยืดหยุ่น
Tom Tom

190

ด้วยทวิ: {{ 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 กล่าวว่า) และไม่ทำงานหากคำขอถูกส่งต่อ ... ดูคำตอบของซูเปอร์โนวา ซึ่งได้รับการบันทึกและมีความปลอดภัยมากกว่า
luiges90

48

ฉันคิดว่านี่เป็นวิธีที่ง่ายที่สุดในการทำสิ่งนี้:

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

    .....

3
คุณสามารถเพิ่มคำอธิบายเพิ่มเติมหรือแสดงผลลัพธ์ตัวอย่างเพื่ออธิบายวิธีการแก้ไขปัญหาได้หรือไม่
Charlie


1
@Charlie มันเป็นตัวแปรที่กำหนดไว้ล่วงหน้าซึ่งให้เส้นทาง "ชื่อ" ที่ตรงกับคุณ
ซูเปอร์โนวา

2
นี่เป็นคำตอบที่ดีที่สุดสำหรับคำถามดั้งเดิม หมายเหตุด้านข้าง: มันใช้งานไม่ได้กับคำขอย่อย{% render "SomeBundle:SomeController:someAction" %}ที่คุณจะได้รับค่า '_internal' อีกครั้ง
netmikey

2
น่าเสียดายที่มันใช้งานได้ในการกระทำดั้งเดิมเท่านั้นสำหรับฟังก์ชั่นอื่น ๆ ที่จะต้องส่งต่อ
Darek Wędrychowski

27

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) { ... }

github.com/symfony/symfony/issues/854ฉันไม่แน่ใจเกี่ยวกับสิ่งนี้$route['_route']ดูเหมือนจะเป็นปัญหา แต่อาจไม่ใช่ sym devony dev ที่พูดถึง ตำราไม่ได้กล่าวถึงเรื่อง_routeการ$router->match()ส่งออก ..
luiges90

ฉันเห็นด้วยอย่างยิ่งกับ @ luiges90 PHPDoc ของ$router->match()บอกว่า "@ อาร์เรย์ย้อนกลับอาร์เรย์ของพารามิเตอร์" ซึ่งดูเหมือนว่าภายในมาก ฉันไม่ต้องการที่จะพึ่งพา แต่ตอนนี้ดูเหมือนว่าจะเป็นทางออกเดียวที่ทำงานได้เมื่อจัดการกับคำขอย่อย
netmikey

19

ไม่มีวิธีแก้ปัญหาที่เหมาะกับทุกกรณีการใช้งาน หากคุณใช้วิธี $ 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');
}

คุณสามารถขยายกิ่งไม้ออกได้ถ้าคุณต้องการในแม่แบบ


ดังนั้น…วิธีการแก้ปัญหาของคุณไม่ทำงานสำหรับการใช้งานทุกกรณีได้อย่างไร
greg0ire

11

_routeไม่ได้เป็นวิธีที่จะไปและไม่เคยเป็น มันมีไว้สำหรับวัตถุประสงค์ในการดีบั๊กตาม Fabien ผู้สร้าง Symfony มันไม่น่าเชื่อถือเพราะจะไม่ทำงานกับสิ่งต่าง ๆ เช่นการส่งต่อและการโทรโดยตรงไปยังคอนโทรลเลอร์เช่นการเรนเดอร์บางส่วน

คุณต้องฉีดชื่อเส้นทางของคุณเป็นพารามิเตอร์ในคอนโทรลเลอร์ดูเอกสารที่นี่

นอกจากนี้โปรดอย่าใช้$request->get('');ถ้าคุณไม่ต้องการความยืดหยุ่นมันเป็นวิธีที่ช้ากว่าการใช้รับในถุงทรัพย์สินเฉพาะที่คุณต้องการ (คุณลักษณะแบบสอบถามหรือคำขอ) ดังนั้น$request->attributes->get('_route');ในกรณีนี้


4
ตกลงโดยทั่วไปคุณแนะนำให้เพิ่มข้อมูลพิเศษให้กับทุกเส้นทางในไฟล์นี้แทนที่จะรับชื่อเส้นทาง …
Charaf

1
โดยเฉพาะอย่างยิ่งถ้าคุณต้องการที่จะสามารถเรียกตัวควบคุมในภายหลังลงบรรทัด (ไปข้างหน้า, การแสดงผลบางส่วน, ฯลฯ ... ) ผ่านชื่อเป็นพารามิเตอร์เป็นวิธีเดียวที่นี่เพราะคุณไม่ได้เรียกเส้นทางในเลย กรณี. สำหรับ _route นั้นมีไว้สำหรับวัตถุประสงค์ในการดีบักอย่านำมันออกมาให้ฉัน ^^ '
Tom Tom

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

คุณสามารถรับชื่อเส้นทางจากวัตถุคำขอจากภายในคอนโทรลเลอร์


4

ทั้งหมดที่ฉันได้รับคือ _internal

ฉันได้รับชื่อเส้นทางจากภายในคอนโทรลเลอร์ด้วย$this->getRequest()->get('_route'). แม้แต่โค้ด tuxedo25 ที่แนะนำให้ส่งคืน_internal

รหัสนี้ทำงานในสิ่งที่เรียกว่า 'Component' ใน Symfony 1.X; ไม่ใช่ตัวควบคุมของหน้า แต่เป็นส่วนหนึ่งของหน้าซึ่งต้องการตรรกะบางอย่าง

รหัสเทียบเท่าใน Symfony 1.X คือ: sfContext::getInstance()->getRouting()->getCurrentRouteName();


2
แก้ไขมันด้วยตัวเอง ในมุมมอง:$view['request']->getParameter('_route');
alexismorin

5
นี้เป็นเพราะคุณกำลังใช้สายที่มี{% render... %} standalone=trueเมื่อเปิดใช้งานการแคช (AppCache.php หรือวานิชกับ ESI) สิ่งนี้จะทำให้มุมมองแบบสแตนด์อโลนได้รับการร้องขอด้วยการร้องขอ HTTP แยกกัน (นี่คือที่_internalมาของการเล่นเส้นทาง) เพื่อให้แคชได้อย่างอิสระ
Martin Schuhfuß

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

ในการรับเส้นทางปัจจุบันตาม 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;
}

0

ด้วย Symfony 4.2.7 ฉันสามารถใช้สิ่งต่อไปนี้ในแม่แบบกิ่งไม้ของฉันซึ่งแสดงชื่อเส้นทางแบบกำหนดเองที่ฉันกำหนดไว้ในคอนโทรลเลอร์ของฉัน

ใน index.html.twig

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

ในตัวควบคุมของฉัน


    ...

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

        ...
     }

ผลลัพธ์จะพิมพ์ "article_list" ไปยังหน้าที่ต้องการในเบราว์เซอร์ของฉัน


0

สำหรับใครที่ต้องการเส้นทางปัจจุบันสำหรับ 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
   $name = $request->get('_route'); // This will return the name.
?>

3
นี่จะไม่ส่งคืนชื่อของเส้นทางที่จัดการ
Nico Haase

@NicoHaase ไม่ใช่วิทยาศาสตร์จรวดคุณมีคำขอวัตถุอยู่แล้ว
Aderemi Dayo

-2

ถ้าคุณต้องการที่จะได้รับชื่อเส้นทางในตัวควบคุมของคุณกว่าที่คุณจะต้องฉีดคำขอ (แทนที่จะได้รับจากภาชนะเนื่องจากSymfony UPGRADE และกว่าโทรได้รับ ('_ เส้นทาง')

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

หากคุณต้องการชื่อเส้นทางเป็นทวิกกว่าที่คุณต้องการ

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

1
ไม่แนะนำให้ใช้$request->get()โดยตรงเนื่องจากช้า: github.com/symfony/http-foundation/blob/2.8/Request.php#L712
ricko zoe
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.