Мы продолжаем изучать Symfony. В первом уроке мы разобрались с установкой и структурой проекта. Сегодня погрузимся в одну из ключевых тем, в маршрутизацию. Без неё ваш сайт не сможет обрабатывать запросы пользователей. Давайте начнём.
Что такое маршрутизация (Routing)?
Маршрутизация это процесс, который связывает URL-адреса с конкретными методами в вашем приложении. Представьте, что пользователь вводит https://ваш-сайт.ru/about
. Задача маршрутизатора это определить, какой контроллер и метод отвечают за генерацию страницы «О нас».
Зачем это нужно?
- Чистая структура URL: Вы можете создавать понятные адреса вроде
/blog/post-123
вместо/index.php?page=blog&id=123
. - Гибкость: Легко менять логику обработки URL без переписывания кода.
- Безопасность: Можно валидировать параметры запроса на уровне маршрутов.
В Symfony маршруты можно создавать тремя способами: через YAML-файлы, аннотации или атрибуты. Но обо всём по порядку.
Создание простых маршрутов в config/routes.yaml
Начнём с классического подхода YAML. Откройте файл config/routes.yaml
. Здесь вы будете описывать маршруты в формате YAML.
Пример 1: Статический маршрут
Допустим, мы хотим создать страницу приветствия по адресу /hello
. Добавьте в routes.yaml
следующий код:
hello_page: path: /hello controller: App\Controller\DefaultController::hello
Что здесь происходит?
hello_page
— уникальное имя маршрута (пригодится для генерации URL в шаблонах).path
— URL-адрес, который будет обрабатываться.controller
— метод контроллера, вызываемый при переходе по этому адресу.
Теперь создайте контроллер DefaultController
:
// src/Controller/DefaultController.php namespace App\Controller; use Symfony\Component\HttpFoundation\Response; class DefaultController { public function hello(): Response { return new Response('Привет, Symfony!'); } }
Перейдите по адресу http://localhost:8000/hello
— вы увидите ваше приветствие!
Пример 2: Маршрут с динамическим URL
Допустим, мы хотим отображать статьи по их ID: /blog/5
. Добавим в routes.yaml
:
blog_show: path: /blog/{id} controller: App\Controller\BlogController::show
А в контроллере:
// src/Controller/BlogController.php namespace App\Controller; use Symfony\Component\HttpFoundation\Response; class BlogController { public function show(int $id): Response { return new Response("Статья №{$id}"); } }
Теперь при переходе на /blog/42
вы увидите: «Статья №42».
Аннотации, YAML, атрибуты
Symfony поддерживает три способа определения маршрутов. Давайте сравним их.
1. YAML
Плюсы:
- Отделение конфигурации от кода.
- Удобно для больших проектов с множеством маршрутов.
Минусы:
- Нужно переключаться между файлами при редактировании.
2. Аннотации (устаревший способ)
Раньше маршруты описывались через PHP-докблоки:
// src/Controller/LegacyController.php use Symfony\Component\Routing\Annotation\Route; class LegacyController { /** * @Route("/old", name="old_route") */ public function oldMethod(): Response { // ... } }
Аннотации это комментарии, которые парсятся в runtime. Это замедляет работу и не поддерживается в PHP 8.1+.
3. Атрибуты (рекомендуется!)
В PHP 8+ появились атрибуты, встроенная возможность языка. Symfony перешла на них:
// src/Controller/NewController.php use Symfony\Component\Routing\Attribute\Route; class NewController { #[Route('/new', name: 'new_route')] public function newMethod(): Response { // ... } }
Преимущества:
- Код и маршруты находятся в одном месте.
- Автодополнение в IDE.
- Лучшая производительность.
Используйте атрибуты, если работаете с Symfony 5.3+ и PHP 8+.
Передача параметров в маршруты
Часто нужно передавать данные через URL. Например, ID статьи или фильтры. Разберёмся, как это сделать.
1. Обязательные параметры
Допустим, мы хотим отображать профиль пользователя по его имени: /user/maxim
.
# config/routes.yaml user_profile: path: /user/{username} controller: App\Controller\UserController::profile
В контроллере:
public function profile(string $username): Response { return new Response("Профиль: {$username}"); }
2. Необязательные параметры
Что если сделать параметр необязательным? Например, /blog
показывает все статьи, а /blog/5
— конкретную.
blog_list: path: /blog/{page} controller: App\Controller\BlogController::list defaults: page: 1
Теперь page
по умолчанию равен 1.
3. Валидация параметров
Чтобы URL /blog/abc
не ломал приложение, добавим проверку типа:
blog_show: path: /blog/{id} controller: App\Controller\BlogController::show requirements: id: '\d+'
Теперь id
должен быть числом. Иначе Symfony вернёт ошибку 404.
Через атрибуты это выглядит так:
#[Route('/blog/{id}', name: 'blog_show', requirements: ['id' => '\d+'])] public function show(int $id): Response { // ... }
Практические задачи
Закрепим знания на практике.
Задача 1: Создайте маршрут для страницы контактов
- URL:
/contact
- Контроллер:
ContactController::index()
- Вывод: «Наши контакты: example@mail.ru».
Решение:
- Добавьте в
routes.yaml
:
contact_page: path: /contact controller: App\Controller\ContactController::index
- Создайте контроллер
ContactController
.
Задача 2: Динамическая страница товара
Создайте маршрут /product/{slug}
, где slug
— строка из букв и дефисов (например, /product/iphone-15
).
Решение:
product_show: path: /product/{slug} controller: App\Controller\ProductController::show requirements: slug: '[a-zA-Z-]+'
Итого 2-го урока
Сегодня мы разобрали основы маршрутизации в Symfony. Вы научились:
- Создавать статические и динамические маршруты.
- Работать с YAML и атрибутами.
- Передавать и валидировать параметры.
В следующих уроках будем изучать контроллеры и шаблоны Twig. Полный курс Symfony для начинающих