Маршрутизація
Concept Core використовує League Route
поверх PSR-7. Маршрути описуються у PHP-файлах; один спільний екземпляр
Concept\Core\Http\Routing\Router (реалізує RouterInterface) обслуговує весь застосунок.
Контекст: життєвий цикл запиту, config/routes.php.
Підключення файлів маршрутів
У config/routes.php задають список файлів (routes.list) і опційно
route interceptors (routes.interceptors). Підключає
HttpServiceProvider при першому створенні RouterInterface:
return [
'routes' => [
'interceptors' => [
// AclRouteAuthorization::class, // RouteInterceptorInterface
],
'list' => [
dirname(__DIR__) . '/routes/web.php',
],
],
];
Додаткові файли з компонентів підключаються під час
ComponentsServiceProvider::boot() — компонент повертає шлях до
routes.php через ComponentInterface::routes()
Див. структура з компонентами.
У кожному файлі маршрутів доступна змінна $router
(тип League\Route\Router / RouterInterface):
<?php declare(strict_types=1);
use League\Route\Router;
/** @var Router $router */
$router->get('/path', $handler);
Глобальні route interceptors (ACL, політики) реєструються в
routes.interceptors — див. окремий розділ
Route interceptors.
Обробники (handlers)
League Route підтримує кілька форм callable:
Контролер [Class, method]
Рекомендований варіант — метод контролера, який резолвиться з DI-контейнера:
use Concept\App\Controllers\IndexController;
$router->get('/', [IndexController::class, 'index'])->setName('home');
Екземпляр контролера та аргументи методу підставляє RouteStrategy
(FormRequest, ServerRequestInterface, параметри URL, Caster).
Детальніше — Контролери.
Closure
use Concept\Core\Http\Contracts\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
$router->get('/health', function (ResponseFactoryInterface $response): ResponseInterface {
return $response->json(['status' => 'ok']);
});
Для простих endpoint-ів; для складної логіки краще винести в контролер.
HTTP-методи
| Метод Router | HTTP |
|---|---|
get() | GET |
post() | POST |
put() | PUT |
patch() | PATCH |
delete() | DELETE |
map() | кілька методів |
Параметри URL
Сегменти в фігурних дужках потрапляють у атрибути запиту та в аргументи handler:
$router->get('/admin/users/edit/{id:number}', [UserController::class, 'edit']);
Суфікс :number — обмеження League Route (лише цифри).
Інші: :alpha, :alphanum, :segment тощо.
Без суфікса — довільний сегмент ({token}).
У контролері параметр з тією ж назвою та типом (через CasterInterface):
public function edit(int $id): ResponseInterface
Групи маршрутів
Спільний префікс URI та middleware для групи:
use League\Route\RouteGroup;
use Concept\Components\AuthAdmin\Middlewares\AuthMiddleware;
$router->group('/admin', function (RouteGroup $route) {
$route->get('/', [AdminController::class, 'index'])->setName('admin.home');
$route->get('/logout', [AdminController::class, 'logout'])->setName('admin.logout');
})->lazyMiddleware(AuthMiddleware::class);
URL /admin та /admin/logout проходять через AuthMiddleware.
Вкладені групи підтримуються.
Middleware на маршрутах
Глобальний — для всіх маршрутів у файлі (зазвичай на початку routes/web.php).
Мінімальний skeleton не підключає middleware
$router->lazyMiddleware(VerifyCsrfTokenMiddleware::class);
$router->lazyMiddleware(ShareViewDataMiddleware::class);
На групу або маршрут — ланцюжок доповнюється для збігів у цій області:
$router->post('/projects/store', [ProjectController::class, 'store'])
->setName('projects.store')
->lazyMiddleware(ActiveUserMiddleware::class);
lazyMiddleware — клас резолвиться з контейнера під час запиту.
Детальніше — Middleware.
Іменовані маршрути
Кожному маршруту можна задати ім’я для генерації URL:
$router->get('/login', [CabinetController::class, 'showLogin'])->setName('cabinet.login');
У PHP через UrlGeneratorInterface:
// шлях від кореня: /admin/users/edit/5
$path = $urlGenerator->uri('admin.user.edit', ['id' => 5]);
// повний URL: https://example.com/admin/users/edit/5
$fullUrl = $urlGenerator->url('admin.user.edit', ['id' => 5]);
$origin = $urlGenerator->base();
Редірект за іменем — ResponseFactoryInterface::redirectByName():
return $this->response->redirectByName('admin.users');
У Twig — AppExtension у skeleton:
{{ uri('cabinet.login') }}
{{ url('admin.user.edit', { id: user.id }) }}
{{ base_url() }}
Маршрути компонентів
Компонент повертає абсолютний шлях до routes.php через
ComponentInterface::routes() (типовий патерн — __DIR__ . '/routes.php').
Приклад: src/Components/AuthAdmin/routes.php з префіксами /admin,
/admin/users.
Усі маршрути потрапляють в один Router — уникайте дублювання імен
(setName) між файлами.
Перегляд маршрутів (CLI)
php bin/console.php route:list
php bin/console.php route:list --full-middleware
php bin/console.php route:list -F
Команда route:list виводить метод, URI, ім’я, handler і middleware.
Потрібен ConsoleServiceProvider і реєстрація RouteListCommand у
config/commands.php (у skeleton уже є).
Поради
- Тримайте публічні маршрути в
routes/web.php, модульні — уComponent/routes.php. - Завжди іменуйте маршрути, які з’являються у шаблонах або редіректах.
- POST/PUT/PATCH/DELETE з формами — разом із
VerifyCsrfTokenMiddlewareі CSRF-полем. - Захищені зони —
group()+ auth-middleware; ACL — route interceptors.