Просмотров: 58 257

Symfony 4. Компонент Form и работа с формами.

Когда нам нужно создать HTML-форму в Symfony, у нас есть 2 основных варианта:

1) Создавать форму напрямую без использования дополнительных компонентов.

2) Воспользоваться специальным компонентом Form.

Эта статья для того, чтобы показать как можно создать простую HTML-форму в Symfony с помощью этих вариантов и кое о чем узнать у вас в конце статьи.

Код, который будет располагаться ниже относится к Symfony версии 4. В Symfony 3 и 2 изменения в коде будут незначительные.

Процесс работы с формами довольно сложный и состоит из нескольких этапов: создание формы, ее отображение, отправка, получение и обработка данных. Из-за большого количества таких этапов многие испытывают трудности при работе с формами.

Чем больше шагов, тем более трудно нашим мозгом воспринимается весь процесс.

Давайте последовательно рассмотрим эти два варианта работы с формами в Symfony.

1 вариант.  Создание формы напрямую, без использования дополнительных компонентов.

Создадим вид, в котором будет размещаться сама форма.

Например, так:

Файл templates/test.html.twig

{% extends 'base.html.twig' %}
{% block body %}
    {{ dump(params) }}
    <form method="post">
        <input type = "text" name = "firstname" value = "Введите имя">
        <input type = "text" name = "lastname" value = "Введите фамилию">
        <input type = "submit" name = "submit" value = "Отправить">
    </form>
{% endblock %}

Выражение {{ dump(params) }} будет отображать POST параметры с отправленной формы. Когда у формы не указан атрибут action, данные передаются на ту же страницу, где размещается сама форма.

Теперь, нужно создать контроллер, который отобразит эту форму и обработает результаты

Файл src/Controller/TestController.php

use Symfony\Component\Routing\Annotation\Route;
...
/**
 * @Route("/testform", name="test_form")
 */
public function testFormAction(Request $request)
{
//Принимаем параметры с формы
$params = $request->request->all(); 
//Отображаем вид с формой и передаем туда полученные параметры.
return $this->render('test.html.twig', array(
'params' => $params
));
}

Попробуем отправить форму и получаем массив с POST параметрами формы.

Метод довольно простой, но не является гибким решением. Если эта форма должна будет располагаться сразу в большом количестве twig файлов, то чтобы внести в нее изменение, нужно будет вносить правки в каждый файл.

Чтобы гибко и универсально работать с формами, воспользуемся компонентом Symfony Form.

2 вариант. Компонент Form.

Давайте начнем с процесса установки компонента Form. Установить его можно с помощью composer:

composer require symfony/form

Создание формы с его помощью начинается с описания конструктива формы. Грубо говоря, мы сообщаем Symfony какие поля будут в нашей форме и какой тип данных в них можно будет ввести.

Описать конструктив формы можно двумя основными способами:

  1. Сразу внутри контроллера (с помощью функции createFormBuilder).
  2. Создав специальный класс. В рамках этой статьи, я выбрал для рассмотрения этот вариант.

Для создания такого конструктива нам понадобиться специальный класс. Принято размещать этот класс в папке Form вашего Symfony приложения, но файл с этим классом может находиться и в папке с другим названием.

Файл src/Form/MyTestForm.php

<?php
namespace App\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
class MyTestForm extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('firstname', TextType::class)
->add('lastname', TextType::class)
;
}
}

Это класс должен обязательно наследоваться от класса AbstractType.

extends AbstractType

Класс состоит всего из одной функции buildForm в которой описывается конструктив формы: из каких полей и какого типа эта форма будет состоять. Это делается с помощью свойства $builder и метода add.

У метода add первым параметром передается название поля формы, а вторым ее тип.

Переходим к контроллеру.

Файл src/Controller/TestController.php

/**
 * @Route("/testform", name="test_form")
 */
public function testAction(Request $request)
{
//Создаем форму из конструктива класса MyTestForm
$form = $this->createForm('App\Form\MyTestForm');
//Обрабатываем данные, которые поступили в запросе и относятся к форме
$form->handleRequest($request);
//Получаем данные введенные в форму.
dump($form->getData());
return $this->render('test.html.twig', array(
'form' => $form->createView()
));
}

И остается только отобразить форму в twig файле (templates/test.html.twig):

{% extends 'base.html.twig' %}
{% block body %}
    {{ form_start(form) }}
    {{ form_row(form.firstname) }}
    {{ form_row(form.lastname) }}
    <input type = "submit" name = "submit" value = "Отправить">
    {{ form_end(form) }}
{% endblock %}

Оператор:

form_start — открывает тэг <form> для формы, которые была создана в контроллере и передана в TWIG элементом массива form.

form_end — закрывает тэг <form>

form_row — выводит поля формы исходя из их названия и конструктива, который был описан для этих полей в классе MyTestForm.

Работа с формами в Symfony 4 имеет очень много особенностей и подводных камней. В этой статье я описал лишь малую часть того, что нужно знать о работе с формами Symfony.

Вот примерный список тем, которые еще желательно изучить, чтобы уверенно работать с Symfony формами.

+ Валидация

+ Вывод ошибок обработки формы

+ Работа с типами полей

+ Работа с флеш-сообщениями

+ Создание форм с помощью createFormBuilder

и.т.д.