Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Вложенные маршруты

У страниц одного раздела адреса начинаются одинаково: /blog, /blog/5, /blog/add. Чтобы не повторять общую часть в каждом маршруте, маршруты вкладывают друг в друга. Вложенный (дочерний) маршрут продолжает адрес родителя и наследует его значения по умолчанию.

Родитель и дочерний маршрут

В прошлом уроке маршруты blog и post были записаны отдельно. Перепишите раздел router в module/Blog/config/module.config.php так:

// module/Blog/config/module.config.php
'router' => [
    'routes' => [
        'blog' => [
            'type' => Literal::class,
            'options' => [
                'route' => '/blog',
                'defaults' => [
                    'controller' => Controller\PostController::class,
                    'action' => 'index',
                ],
            ],
            'may_terminate' => true,
            'child_routes' => [
                'view' => [
                    'type' => Segment::class,
                    'options' => [
                        'route' => '/:id',
                        'constraints' => ['id' => '[0-9]+'],
                        'defaults' => ['action' => 'view'],
                    ],
                ],
            ],
        ],
    ],
],

Адрес дочернего маршрута приклеивается к адресу родителя: /blog плюс /:id даёт /blog/5. Контроллер у дочернего маршрута не указан — он взят у родителя, меняется только действие.

Ключ may_terminate

'may_terminate' => true означает, что адрес родителя — /blog — тоже рабочая страница. Без этого ключа сработают только дочерние маршруты, а сам /blog вернёт ошибку 404.

Все маршруты блога

Добавьте в child_routes ещё три маршрута — они понадобятся в следующих уроках:

'add' => [
    'type' => Literal::class,
    'options' => [
        'route' => '/add',
        'defaults' => ['action' => 'add'],
    ],
],
'edit' => [
    'type' => Segment::class,
    'options' => [
        'route' => '/edit/:id',
        'constraints' => ['id' => '[0-9]+'],
        'defaults' => ['action' => 'edit'],
    ],
],
'delete' => [
    'type' => Segment::class,
    'options' => [
        'route' => '/delete/:id',
        'constraints' => ['id' => '[0-9]+'],
        'defaults' => ['action' => 'delete'],
    ],
],

Получается такая таблица:

Имя маршрутаАдресДействие
blog/blogindex
blog/view/blog/5view
blog/add/blog/addadd
blog/edit/blog/edit/5edit
blog/delete/blog/delete/5delete

Имена вложенных маршрутов

Имя дочернего маршрута записывают через косую черту после имени родителя. Ссылку на статью теперь строят так:

$url = $this->url('blog/view', ['id' => 5]); // /blog/5

Отдельного маршрута post из прошлого урока больше нет — его заменил blog/view.

Частая ошибка

Если обратиться к дочернему маршруту без имени родителя — $this->url('view', ['id' => 5]), — Laminas выбросит исключение о том, что маршрут с таким именем не найден. Имя всегда полное: blog/view. Вторая похожая ошибка — забытый may_terminate: дочерние страницы открываются, а /blog отвечает 404.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.