Новое в Symfony 4.
3: Безусловное включение в URL необязательного параметра маршрутаУдальцов ВалентинBlockedUnblockFollowFollowingJan 2Перевод статьи New in Symfony 4.
3: Always Include Route Default Values.
Маршрутизация в Symfony позволяет указать значение по умолчанию для параметра маршрута.
При генерации URL последний параметр маршрута будет опущен, если его значение не передано или совпадает со значением по умолчанию.
Рассмотрим пример:namespace AppController;use SymfonyBundleFrameworkBundleControllerAbstractController;use SymfonyComponentRoutingAnnotationRoute;class BlogController extends AbstractController{ /** * @Route("/blog/{page}", name="blog_list") */ public function list($page = 1) { // .
}}Если вы не укажете значение параметра page при генерации URL на базе маршрута blog_list, результирующим URL будет /blog, а аргумент page будет равен 1:$router = .
// экземпляр UrlGeneratorInterface$url = $router->generate('blog_list'); // /blog$url = $router->generate('blog_list', ['page' => 1]); // /blog/1$url = $router->generate('blog_list', ['page' => 7]); // /blog/7Как правило, это желаемое поведение в большинстве ситуаций.
Но иногда последний параметр должен присутствовать в сгенерированном URL вне зависимости от того, передано значение или нет.
В Symfony 4.
3 это станет возможным благодаря обновленному синтаксису маршрута:/** * @Route("/blog/{!page}", name="blog_list") */public function list($page = 1){ // .
}Восклицательный знак !.перед именем параметра сообщает роутеру о том, что параметр должен быть включен в URL безусловно:$url = $router->generate('blog_list'); // /blog/1$url = $router->generate('blog_list', ['page' => 1]); // /blog/1$url = $router->generate('blog_list', ['page' => 7]); // /blog/Добавлено Владимиром Лучаниновым в #29599.
От переводчикаПредлагаю рассмотреть еще один пример из пояснения к PR.
ЗадачаОрганизовать маршрутизацию для экспорта новостей в форматах CSV и XML с использованием системного параметра _format.
Формат по умолчанию CSV.
Расширение должно всегда присутствовать в URL с целью повышения его информативности.
Вариант 1Зашить расширение в путь и присвоить атрибут вручную:@Route("/news/export.
csv", name="news_export", defaults={"_format": "csv"})@Route("/news/export.
xml", name="news_export_xml", defaults={"_format": "xml"})Выглядит избыточно; очень неудобно в использовании из-за двух маршрутов.
Вариант 2Оставить расширение обязательным параметром:@Route("/news/export.
{_format<csv|xml>}", name="news_export")Придется всегда указывать формат {{ path('export_news', {_format: 'csv'}) }}.
Symfony 4.
3@Route("/news/export.
{!_format<csv|xml>?csv}", name="news_export")Итак, в Symfony 4.
3 при помощи записи {!slug} мы сможем гарантировать наличие параметра slug в сгенерированном URL вне зависимости от его значения.
.