Маршрутизация (роутинг)

В JohnCMS маршрутизация построена на Johncms\Router\RouteCollection и Symfony Routing.

Эта страница описывает текущий подход: как объявлять маршруты, как подключать middleware, какие бывают обработчики и как происходит dispatch.

Где описываются маршруты

  • Основные маршруты системы: config/routes.php

  • Ваши дополнительные маршруты: config/routes.local.php

Для собственного кода используйте routes.local.php, чтобы изменения не терялись при обновлениях.

Пример есть в файле config/routes.local.php.example.

Базовый пример маршрута

<?php

declare(strict_types=1);

/** @var \Johncms\Router\RouteCollection $router */

$router->get('/contacts', 'modules/contacts/index.php');
$router->map(['GET', 'POST'], '/feedback', 'modules/feedback/index.php');

Параметры и ограничения

Маршрут может содержать параметры и ограничения через requirements():

Также поддерживаются пресеты в пути:

  • {id:number}

  • {article_code:slug}

  • {category:path}

Примеры можно посмотреть в config/routes.php.

Middleware на маршрутах

Middleware — это промежуточный обработчик между совпавшим маршрутом и его handler. Он получает Request, может выполнить проверку/подготовку и передать управление дальше через $next($request).

Обычно middleware используют для:

  • проверки доступа (права, авторизация, владение ресурсом)

  • валидации обязательных условий перед действием

  • логирования и других сквозных задач

Middleware для конкретного маршрута

Добавление middleware к одному маршруту:

Можно указывать несколько middleware, они будут вызваны по порядку добавления.

Middleware для группы/коллекции маршрутов

Можно добавить middleware сразу на коллекцию (например, в группе):

Такой middleware будет применяться ко всем маршрутам внутри этой коллекции.

Допустимые типы middleware

Middleware может быть:

  • классом (получается из контейнера), реализующим Johncms\Router\MiddlewareInterface

  • callable

Контракт middleware для класса:

Пример класса middleware:

Пример callable middleware:

Порядок выполнения

При обработке совпавшего маршрута выполняется цепочка:

  1. middleware коллекции/группы

  2. middleware самого маршрута

  3. handler маршрута

Если middleware не вызывает $next($request), цепочка останавливается и handler не будет вызван.

Какие обработчики поддерживаются

В маршруте можно указать:

  1. Строку с путем legacy-файла ('modules/contacts/index.php')

  2. Invokable-контроллер (SomeController::class с __invoke())

  3. Массив [ControllerClass::class, 'method']

Это обрабатывается в index.php через ActionInvoker и MiddlewareDispatcher.

Как работает dispatch

Схема обработки запроса:

  1. URI нормализуется в index.php

  2. SymfonyRouteMatcher::dispatch() пытается сопоставить маршрут

  3. При FOUND:

    • route params кладутся в request

    • запускается цепочка middleware

    • вызывается handler

  4. При METHOD_NOT_ALLOWED возвращается 405 Method Not Allowed

  5. При NOT_FOUND вызывается pageNotFound()

Типовые ошибки

404 Not Found

Причины:

  • путь не совпадает с шаблоном маршрута

  • route params не прошли requirements

  • маршрут не зарегистрирован в routes.php/routes.local.php

405 Method Not Allowed

Причина:

  • URL найден, но HTTP-метод не разрешен для маршрута (например, POST вместо GET).

Ошибка middleware

Причины:

  • middleware-класс не зарегистрирован в контейнере

  • middleware не callable и не реализует MiddlewareInterface

В этом случае MiddlewareDispatcher выбросит InvalidArgumentException.

См. также

Последнее обновление

Это было полезно?