Маршруты
Маршрут связывает адрес страницы с кодом, который формирует ответ. В Laminas нет общего файла с адресами: каждый модуль описывает свои маршруты в разделе router файла module/<Модуль>/config/module.config.php.
Первый маршрут
Откройте module/Blog/config/module.config.php и замените пустой массив:
// module/Blog/config/module.config.php
namespace Blog;
use Laminas\Router\Http\Literal;
return [
'router' => [
'routes' => [
'blog' => [
'type' => Literal::class,
'options' => [
'route' => '/blog',
'defaults' => [
'controller' => Controller\PostController::class,
'action' => 'index',
],
],
],
],
],
];Что означает каждый ключ:
| Ключ | Значение |
|---|---|
blog | Имя маршрута. По нему потом строят ссылки |
type | Тип маршрута. Literal — точное совпадение адреса |
route | Сам адрес |
defaults.controller | Класс контроллера, который ответит на запрос |
defaults.action | Действие — метод контроллера indexAction() |
Откройте http://localhost:8080/blog. Появится страница ошибки с пояснением, что контроллер не найден. Это ожидаемо: маршрут уже сработал, а класс PostController будет создан в уроке о контроллерах. До добавления маршрута тот же адрес отвечал, что страница не найдена.
Маршрут с параметром
Тип Segment позволяет вставить в адрес изменяемую часть — параметр. Параметр начинается с двоеточия. Добавьте второй маршрут рядом с первым, внутрь routes:
// в начале файла: use Laminas\Router\Http\Segment;
'post' => [
'type' => Segment::class,
'options' => [
'route' => '/blog/:id',
'constraints' => [
'id' => '[0-9]+',
],
'defaults' => [
'controller' => Controller\PostController::class,
'action' => 'view',
],
],
],Адрес /blog/5 попадёт в действие view, а число 5 станет параметром id. Раздел constraints задаёт регулярное выражение для параметра: здесь id — только цифры, поэтому /blog/anna этому маршруту не подойдёт.
Необязательная часть
Часть адреса в квадратных скобках можно не указывать. Значение по умолчанию берётся из defaults:
'archive' => [
'type' => Segment::class,
'options' => [
'route' => '/archive[/:year]',
'constraints' => ['year' => '[0-9]{4}'],
'defaults' => [
'controller' => Controller\PostController::class,
'action' => 'archive',
'year' => 2025,
],
],
],Маршрут ответит и на /archive, и на /archive/2024. В первом случае year будет равен 2025.
Типы маршрутов
| Тип | Для чего |
|---|---|
Literal | Точный адрес без параметров — самый быстрый |
Segment | Адрес с параметрами: /:id, /:year/:month |
Regex | Адрес по регулярному выражению |
Method | Ограничение по методу HTTP |
Ссылка на маршрут
Адреса не пишут в коде вручную — их строят по имени маршрута. В шаблоне это делает помощник url(): вызов $this->url('post', ['id' => 5]) вернёт строку /blog/5. Если адрес в настройках изменится, все ссылки изменятся вместе с ним.
Частая ошибка
Параметр без ограничения принимает любой текст. Маршрут /blog/:id без constraints сработает и для адреса /blog/add, и действие получит id, равный add. Всегда задавайте ограничение для числовых параметров: 'id' => '[0-9]+'.