Ответ
Путь запроса в Symfony строго определён и централизован через фронт-контроллер public/index.php.
- Браузер отправляет HTTP-запрос (например,
GET /blog/42). - Веб-сервер (Nginx/Apache) перенаправляет все запросы на
public/index.php(через конфигурацию, например,try_files $uri /index.php$is_args$args). - Фронт-контроллер (
index.php):- Загружает автозагрузчик Composer.
- Создаёт экземпляр ядра приложения (
Kernel). - Вызывает
Kernel::handle($request), передавая объектRequest, сформированный из глобальных переменных ($_GET,$_POST, etc.).
- Ядро (Kernel):
- Инициализирует контейнер служб (Service Container), загружая конфигурацию из
config/. - Запускает
HttpKernel— основной компонент, обрабатывающий запрос по событийной модели.
- Инициализирует контейнер служб (Service Container), загружая конфигурацию из
- Маршрутизатор (Router):
HttpKernelчерезRouterListener(подписчик на событиеkernel.request) передаётRequestвRouter.Routerсопоставляет путь (/blog/42) с объявленными маршрутами (изconfig/routes/, атрибутов#[Route]или аннотаций).- Находит совпадение и возвращает параметры маршрута:
_controller(например,AppControllerBlogController::show) иid: 42.
- Контроллер (Controller):
HttpKernelчерезControllerResolverсоздаёт или извлекает из контейнера экземплярBlogController.- Вызывает метод
show($id), автоматически подставляя42в аргумент.
Пример контроллера с атрибутом:
// src/Controller/BlogController.php
namespace AppController;
use SymfonyBundleFrameworkBundleControllerAbstractController;
use SymfonyComponentHttpFoundationResponse;
use SymfonyComponentRoutingAttributeRoute;
class BlogController extends AbstractController
{
#[Route('/blog/{id}', name: 'blog_show')]
public function show(int $id): Response
{
// Логика получения статьи по $id
$article = ...;
return $this->render('blog/show.html.twig', ['article' => $article]);
}
}
После выполнения метода контроллера HttpKernel продолжает работу, обрабатывая результат (например, рендеринг шаблона) и отправляя финальный Response.
Ответ 18+ 🔞
Давай разберём, как этот ваш запрос по Symfony шатается, чтобы ты не думал, что там магия какая-то. Представь, что это как доставка пиццы, только вместо курьера — куча компонентов, которые друг другу мозги ебут.
Вот смотри, как всё происходит, по шагам.
- Браузер тупо стучится на твой сайт, типа
GET /blog/42. Ждёт, сука, ответа. - Веб-сервер (Nginx или этот старый пердун Apache) получает запрос. Его конфиг настроен так, что всё, что не статичный файл, он пихает в одну точку —
public/index.php. Типа "разбирайтесь там сами, мне похуй". - Точка входа (
index.php) — это как швейцар в строгом подъезде. Его работа:- Поднять автозагрузчик Composer (чтобы классы сами находились, ёпта).
- Создать ядро приложения (
Kernel). - Засунуть в это ядро сформированный запрос (
Request) и крикнуть:Kernel::handle($request), мол, держи, разгребай!
- Ядро (
Kernel) — тут начинается мясо. Оно:- Поднимает контейнер служб — это такая большая умная тумбочка, где лежат все нужные сервисы (роутер, база данных, почта и прочая хуйня). Конфиги из папки
config/как раз говорят, что в каком ящике лежит. - Передаёт управление главному мозгу —
HttpKernel. Этот товарищ работает на событиях, как параноик на прослушке.
- Поднимает контейнер служб — это такая большая умная тумбочка, где лежат все нужные сервисы (роутер, база данных, почта и прочая хуйня). Конфиги из папки
- Маршрутизатор (
Router) — самый важный этап.HttpKernelкричит событие "я получил запрос!". Его подслушиваетRouterListenerи суёт запрос вRouter.Router— это такой дохуя умный картограф. Он берёт путь (/blog/42) и начинает листать все объявленные маршруты. Ищет где? Да везде: в файликахconfig/routes/, в атрибутах#[Route]над методами контроллеров (раньше в аннотациях).- Находит совпадение и выдаёт на-гора: "Так, контроллер —
AppControllerBlogController::show, аidу них там равен42". Всё, его работа сделана.
- Контроллер (
Controller) — звезда вечера.HttpKernelчерез своего помощника (ControllerResolver) либо создаёт этот контроллер, либо достаёт его готовеньким из той самой умной тумбочки (контейнера).- И просто вызывает метод
show($id), автоматом подсовывая ему42в аргумент. Вот и вся магия, ёпта.
- И просто вызывает метод
А вот как этот самый контроллер может выглядеть. Смотри, ничего сложного:
// src/Controller/BlogController.php
namespace AppController;
use SymfonyBundleFrameworkBundleControllerAbstractController;
use SymfonyComponentHttpFoundationResponse;
use SymfonyComponentRoutingAttributeRoute;
class BlogController extends AbstractController
{
#[Route('/blog/{id}', name: 'blog_show')]
public function show(int $id): Response
{
// Тут твоя логика: достаёшь статью из базы по этому id
$article = ...; // Найди её, блядь!
// И рендеришь шаблон, отдавая ему статью
return $this->render('blog/show.html.twig', ['article' => $article]);
}
}
Контроллер отработал, вернул ответ. HttpKernel это подхватывает, может ещё какие-то события по пути обработать (например, шаблон отрендерить), и в конце концов плюёт готовый Response обратно в браузер. Всё, довольный пользователь видит статью, даже не подозревая, какой пиздец только что произошёл у него под капотом.