Как определять требования маршрутов¶
Требования маршрутов могут быть использованы так, чтобы
определённый маршрут соответствовал только при определённых условиях. Простейший пример
включает в себя ограничение маршрута {wildcard}
так, чтобы он соответствовал
только некоторым регулярным выражениям:
- Annotations
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// src/Controller/BlogController.php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\Routing\Annotation\Route; class BlogController extends Controller { /** * @Route("/blog/{page}", name="blog_list", requirements={"page"="\d+"}) */ public function list($page) { // ... } }
- YAML
1 2 3 4 5 6
# config/routes.yaml blog_list: path: /blog/{page} controller: App\Controller\BlogController::list requirements: page: '\d+'
- XML
1 2 3 4 5 6 7 8 9 10 11 12 13 14
<!-- config/routes.xml --> <?xml version="1.0" encoding="UTF-8" ?> <routes xmlns="http://symfony.com/schema/routing" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd"> <route id="blog_list" path="/blog/{page}"> <default key="_controller">App\Controller\BlogController::list</default> <requirement key="page">\d+</requirement> </route> <!-- ... --> </routes>
- PHP
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// config/routes.php use Symfony\Component\Routing\RouteCollection; use Symfony\Component\Routing\Route; $collection = new RouteCollection(); $collection->add('blog_list', new Route('/blog/{page}', array( '_controller' => 'App\Controller\BlogController::list', ), array( 'page' => '\d+', ))); // ... return $collection;
Благодаря требованию \d+
(т.е. “числовое значение” любой длины), /blog/2
будет
соответствовать этому маршруту, но /blog/some-string
- не будет.
Так как требования параметров - это регулярный выражения, сложность и гибкость каждого требования полностью зависит от вас. Представьте, что домашняя страница вашего приложения доступна на двух разных языках, основываясь на URL:
- Annotations
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// src/Controller/MainController.php // ... class MainController extends Controller { /** * @Route("/{_locale}", defaults={"_locale"="en"}, requirements={ * "_locale"="en|fr" * }) */ public function homepage($_locale) { } }
- YAML
1 2 3 4 5 6 7
# config/routes.yaml homepage: path: /{_locale} controller: App\Controller\MainController::homepage defaults: { _locale: en } requirements: _locale: en|fr
- XML
1 2 3 4 5 6 7 8 9 10 11 12 13
<!-- config/routes.xml --> <?xml version="1.0" encoding="UTF-8" ?> <routes xmlns="http://symfony.com/schema/routing" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd"> <route id="homepage" path="/{_locale}"> <default key="_controller">App\Controller\MainController::homepage</default> <default key="_locale">en</default> <requirement key="_locale">en|fr</requirement> </route> </routes>
- PHP
1 2 3 4 5 6 7 8 9 10 11 12 13
// config/routes.php use Symfony\Component\Routing\RouteCollection; use Symfony\Component\Routing\Route; $collection = new RouteCollection(); $collection->add('homepage', new Route('/{_locale}', array( '_controller' => 'App\Controller\MainController::homepage', '_locale' => 'en', ), array( '_locale' => 'en|fr', ))); return $collection;
Для входящих запросов, часть URL {_locale}
соответствует регулярному
выражению (en|fr)
.
Путь | Параметры |
---|---|
/ |
{_locale} = "en" |
/en |
{_locale} = "en" |
/fr |
{_locale} = "fr" |
/es |
не будет соответствовать этому маршруту |
Note
Вы можете подключить сопоставление маршрутов UTF-8, установив опцию
utf8
при объявлении или импортировании маршрутов. Таким образом,
к примеру, .
в требованиях будет совпадать с любыми символами UTF-8,
а не только с одним байтом.
Tip
Требования маршрутов также могут включать в себя параметры контейнеров, как объявсняется в этой статье. Это может быть полезным, когда регулярное выражение очень сложное и многократно используется в вашем приложении.
Добавление требований HTTP-методов¶
В дополнение к URL, вы также можете использовать соответствие в методе входящего запроса (т.е. GET, HEAD, POST, PUT, DELETE). Представьте, что вы создаёте API для вашего блога, и у вас есть 2 маршрута: один для отображения записи (по запросу GET или HEAD), и один для обновления записи (по запросу PUT). Этого можно достичь с помощью следующей конфигурации маршрута:
- Annotations
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
// src/Controller/BlogApiController.php namespace App\Controller; // ... class BlogApiController extends Controller { /** * @Route("/api/posts/{id}", methods={"GET","HEAD"}) */ public function show($id) { // ... return a JSON response with the post } /** * @Route("/api/posts/{id}", methods="PUT") */ public function edit($id) { // ... edit a post } }
- YAML
1 2 3 4 5 6 7 8 9 10
# config/routes.yaml api_post_show: path: /api/posts/{id} controller: App\Controller\BlogApiController::show methods: [GET, HEAD] api_post_edit: path: /api/posts/{id} controller: App\Controller\BlogApiController::edit methods: [PUT]
- XML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
<!-- config/routes.xml --> <?xml version="1.0" encoding="UTF-8" ?> <routes xmlns="http://symfony.com/schema/routing" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd"> <route id="api_post_show" path="/api/posts/{id}" methods="GET|HEAD"> <default key="_controller">App\Controller\BlogApiController::show</default> </route> <route id="api_post_edit" path="/api/posts/{id}" methods="PUT"> <default key="_controller">App\Controller\BlogApiController::edit</default> </route> </routes>
- PHP
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// config/routes.php use Symfony\Component\Routing\RouteCollection; use Symfony\Component\Routing\Route; $collection = new RouteCollection(); $collection->add('api_post_show', new Route('/api/posts/{id}', array( '_controller' => 'App\Controller\BlogApiController::show', ), array(), array(), '', array(), array('GET', 'HEAD'))); $collection->add('api_post_edit', new Route('/api/posts/{id}', array( '_controller' => 'App\Controller\BlogApiController::edit', ), array(), array(), '', array(), array('PUT'))); return $collection;
Несмотря на тот факт, что эти два маршрута имеют идентичные пути
(/api/posts/{id}
), первый маршрут будет соответствовать только запросам
GET или HEAD, а второй - только запросам PUT. Это означает, что вы можете отобразить
и изменить запись с одним и тем же URL, используя отдельные контроллеры для двух
действий.
Note
Если не указано никаких methods
(методов), то маршрут будет соответствовать
всем методам.
Tip
Если вы используете HTML-формы и HTTP-методы кроме GET
и POST
,
вам понадобится включить параметр _method
чтобы сымитировать HTTP-метод.
См. /form/action_method, чтобы узнать больше.
Добавление требования хоста¶
Вы также можете использовать соответствие в HTTP хосте входящего запроса. Чтобы узнать больше об этом, см. /routing/hostname_pattern в документации компонента Маршрутизация.
Добавление динамических требований с выражениями¶
Для очень сложных требований вы можете использовать динамические выражения для соответствия любой информации по запросу. Смотрите Условия маршрутизации.
Эта документация является переводом официальной документации Symfony и предоставляется по свободной лицензии CC BY-SA 3.0.