Урок 5: Работа с формами в Symfony

На 5-ом уроке мы изучим в одну из тем Symfony, это создание и обработку форм. Формы это неотъемлемая часть веб-приложений: «регистрация, авторизация, отправка данных и т.д.». Symfony предлагает мощный инструментарий для работы с ними. Давайте начнём.

Создание форм с FormBuilder

Первым делом научимся создавать формы с помощью FormBuilder. Этот компонент Symfony позволяет генерировать формы на основе PHP-классов, связывать их с сущностями (Entity) и легко настраивать.

Шаг 1: Создание класса формы

Предположим, у нас есть сущность Article. Создадим для неё форму:

php
// src/Form/ArticleType.php
namespace App\Form;

use App\Entity\Article;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;

class ArticleType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder
            ->add('title', TextType::class, [
                'label' => 'Заголовок статьи',
            ])
            ->add('content', TextareaType::class, [
                'label' => 'Текст статьи',
            ])
            ->add('save', SubmitType::class, [
                'label' => 'Сохранить',
            ]);
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'data_class' => Article::class,
        ]);
    }
}
  • FormBuilder позволяет добавлять поля через метод add().
  • Каждое поле имеет тип (например, TextTypeTextareaType) и опции (например, label).
  • data_class связывает форму с сущностью Article.

Шаг 2: Отображение формы в шаблоне

Теперь выведем форму в Twig:

twig
{# templates/article/new.html.twig #}
{{ form_start(form) }}
    {{ form_widget(form) }}
{{ form_end(form) }}

Это минимальный код для рендеринга всех полей формы. Но позже мы научимся кастомизировать её!

Валидация данных формы

Symfony интегрирует валидацию через компонент Validator. Добавим проверки для сущности Article:

Шаг 1: Добавление аннотаций валидации

php
// src/Entity/Article.php
namespace App\Entity;

use Symfony\Component\Validator\Constraints as Assert;

class Article
{
    /**
     * @Assert\NotBlank(message="Заголовок не может быть пустым!")
     * @Assert\Length(
     *     min=5,
     *     max=100,
     *     minMessage="Заголовок должен быть не короче 5 символов",
     *     maxMessage="Заголовок должен быть не длиннее 100 символов"
     * )
     */
    private string $title;

    /**
     * @Assert\NotBlank(message="Текст статьи обязателен!")
     */
    private string $content;
}
  • @Assert\NotBlank проверяет, что поле не пустое.
  • @Assert\Length задаёт ограничения по длине.

Шаг 2: Вывод ошибок в шаблоне

Чтобы показать ошибки, модифицируем шаблон:

twig
{{ form_start(form) }}
    {{ form_errors(form) }} {# Общие ошибки формы #}

    {{ form_label(form.title) }}
    {{ form_widget(form.title) }}
    {{ form_errors(form.title) }} {# Ошибки для title #}

    {{ form_label(form.content) }}
    {{ form_widget(form.content) }}
    {{ form_errors(form.content) }}

    {{ form_widget(form.save) }}
{{ form_end(form) }}

Кастомизация шаблонов форм

Стандартный вид форм Symfony часто не подходит под дизайн проекта. Научимся менять их!

Шаг 1: Использование тем оформления

Добавим тему для форм в config/packages/twig.yaml:

yaml
twig:
    form_themes: ['bootstrap_5_layout.html.twig'] # Используем стили Bootstrap 5

Теперь все формы будут стилизованы под Bootstrap.

Шаг 2: Ручная кастомизация полей

Переопределим рендеринг поля title:

twig
{% form_theme form _self %} {# Подключаем локальную тему #}

{% block _article_title_widget %}
    <div class="mb-3">
        {{ form_label(form, null, {'label_attr': {'class': 'form-label'}}) }}
        {{ form_widget(form, {'attr': {'class': 'form-control'}}) }}
        {{ form_errors(form, {'attr': {'class': 'text-danger'}}) }}
    </div>
{% endblock %}
  • _article_title_widget — имя блока для поля title формы ArticleType.
  • attr позволяет добавлять HTML-атрибуты (например, классы).

Обработка отправки формы в контроллере

Теперь свяжем форму с контроллером.

Шаг 1: Создание действия

php
// src/Controller/ArticleController.php
namespace App\Controller;

use App\Entity\Article;
use App\Form\ArticleType;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class ArticleController extends AbstractController
{
    public function new(Request $request, EntityManagerInterface $em): Response
    {
        $article = new Article();
        $form = $this->createForm(ArticleType::class, $article);

        $form->handleRequest($request);
        if ($form->isSubmitted() && $form->isValid()) {
            $em->persist($article);
            $em->flush();

            $this->addFlash('success', 'Статья сохранена!');
            return $this->redirectToRoute('article_show', ['id' => $article->getId()]);
        }

        return $this->render('article/new.html.twig', [
            'form' => $form->createView(),
        ]);
    }
}
  • handleRequest() связывает данные запроса с формой.
  • isSubmitted() проверяет, отправлена ли форма.
  • isValid() запускает валидацию.

Практические задачи

  1. Создайте форму регистрации пользователя
    • Добавьте поля: emailpasswordagreeTerms (CheckboxType).
    • Настройте валидацию для email (должен быть валидным) и пароля (минимум 6 символов).
  2. Кастомизируйте форму
    • Стилизуйте кнопку отправки с помощью CSS-класса btn-primary.
    • Добавьте подсказку к полю email: «Введите действующий адрес».
  3. Реализуйте обработку формы в контроллере
    • Сохраняйте пользователя в базе данных.
    • При успешной регистрации перенаправляйте на страницу входа.

Пример кода для задачи 1:

php
// src/Form/UserType.php
public function buildForm(FormBuilderInterface $builder, array $options): void
{
    $builder
        ->add('email', EmailType::class)
        ->add('password', PasswordType::class)
        ->add('agreeTerms', CheckboxType::class, [
            'label' => 'Я согласен с условиями',
        ])
        ->add('submit', SubmitType::class);
}

Сегодня мы разобрали создание форм, их валидацию, кастомизацию и обработку. Это база для работы с любыми формами в Symfony. Пробуйте сами с разными типами полей и стилями.

Полный курс по Symfony для начинающих по ссылке: https://max-gabov.ru/symphony-dlya-nachinaushih

Поделиться статьей:
Поддержать автора блога

Поддержка автора осуществляется с помощью специальной формы ниже, предоставленной сервисом «ЮMoney». Все платёжные операции выполняются на защищённой странице сервиса, что обеспечивает их корректность и полную безопасность.

Персональные рекомендации
Оставить комментарий