Как определять необязательные заполнители

Чтобы сделать всё более захватывающим, добавьте новый маршрут, который отображает список всех доступных записей блога для этого воображаемого приложения-блога:

  • Annotations
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    // src/AppBundle/Controller/BlogController.php
    
    // ...
    class BlogController extends Controller
    {
        // ...
    
        /**
         * @Route("/blog")
         */
        public function indexAction()
        {
            // ...
        }
    }
    
  • YAML
    1
    2
    3
    4
    # app/config/routing.yml
    blog:
        path:      /blog
        defaults:  { _controller: AppBundle:Blog:index }
    
  • XML
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    <!-- app/config/routing.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" path="/blog">
            <default key="_controller">AppBundle:Blog:index</default>
        </route>
    </routes>
    
  • PHP
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    // app/config/routing.php
    use Symfony\Component\Routing\RouteCollection;
    use Symfony\Component\Routing\Route;
    
    $collection = new RouteCollection();
    $collection->add('blog', new Route('/blog', array(
        '_controller' => 'AppBundle:Blog:index',
    )));
    
    return $collection;
    

Пока этот маршрут настолько прост, насколько это возможно - он не содержит заполнителей и будет соответствовать только точному URL /blog. Но что, если вам нужно, чтобы этот маршрут поддерживал нумерацию страниц, где /blog/2 отображает вторую страницу записей блога? Обновите маршрут так, чтобы в нем был новый заполнитель {page}:

  • Annotations
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    // src/AppBundle/Controller/BlogController.php
    
    // ...
    
    /**
     * @Route("/blog/{page}")
     */
    public function indexAction($page)
    {
        // ...
    }
    
  • YAML
    1
    2
    3
    4
    # app/config/routing.yml
    blog:
        path:      /blog/{page}
        defaults:  { _controller: AppBundle:Blog:index }
    
  • XML
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    <!-- app/config/routing.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" path="/blog/{page}">
            <default key="_controller">AppBundle:Blog:index</default>
        </route>
    </routes>
    
  • PHP
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    // app/config/routing.php
    use Symfony\Component\Routing\RouteCollection;
    use Symfony\Component\Routing\Route;
    
    $collection = new RouteCollection();
    $collection->add('blog', new Route('/blog/{page}', array(
        '_controller' => 'AppBundle:Blog:index',
    )));
    
    return $collection;
    

Как и в заполнителе {slug} раньше, значение, соответствующее {page} будет доступно внутри вашего контроллера. Его значение может быть использовано для определения того, какой набор записей блога нужно отобразить для заданной страницы.

Но погодите-ка! Так как заполнители требуются по умолчанию, этот маршрут больше не будет соответствовать просто /blog. Вместо этого, чтобы увидеть 1-ую страницу блога, вам нужно использовать URL /blog/1! Так как это неподобающее поведение для богатого веб-приложения, измените маршрут так, чтобы параметр {page} был необязательным. Это делается путём включения его в коллекцию defaults:

  • Annotations
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    // src/AppBundle/Controller/BlogController.php
    
    // ...
    
    /**
     * @Route("/blog/{page}", defaults={"page" = 1})
     */
    public function indexAction($page)
    {
        // ...
    }
    
  • YAML
    1
    2
    3
    4
    # app/config/routing.yml
    blog:
        path:      /blog/{page}
        defaults:  { _controller: AppBundle:Blog:index, page: 1 }
    
  • XML
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    <!-- app/config/routing.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" path="/blog/{page}">
            <default key="_controller">AppBundle:Blog:index</default>
            <default key="page">1</default>
        </route>
    </routes>
    
  • PHP
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    // app/config/routing.php
    use Symfony\Component\Routing\RouteCollection;
    use Symfony\Component\Routing\Route;
    
    $collection = new RouteCollection();
    $collection->add('blog', new Route('/blog/{page}', array(
        '_controller' => 'AppBundle:Blog:index',
        'page'        => 1,
    )));
    
    return $collection;
    

Добавляя page к ключу defaults, заполнитель {page} больше не является обязательным. URL /blog ,удет соответствовать этому маршруту, а значение параметра page будет установлено как 1. URL /blog/2 также будет соответствовать, предоставляя параметру page значение 2. Идеально.

URL Маршрут Параметры
/blog blog {page} = 1
/blog/1 blog {page} = 1
/blog/2 blog {page} = 2

Caution

Конечно же, у вас может быть больше одного необязательного заполнителя (например, /blog/{slug}/{page}), но всё после необязательного заполнителя также должно быть необязательным. Например, /{page}/blog - валидный путь, но page всегда будет обязательным (т.е. просто /blog не будет соответствовать этому маршруту).

Tip

Маршруты с необязательными параметрами в итоге не будут соответствовать запросам с закрывающим слешем (т.е. /blog/ не будет соответствовать, а /blog - будет).

Эта документация является переводом официальной документации Symfony и предоставляется по свободной лицензии CC BY-SA 3.0.