Формы
Дата обновления перевода 2024-07-29
Формы
Screencast
Предпочитаете видео-уроки? Посмотрите Symfony Forms screencast series.
Создание и обработка HTML форм - это сложно и монотонно. Вам нужно разбираться с отображением полей HTML формы, валидацией отправленных данных, отображением данных формы в объектах и многим другим. Symfony содержит мощную функциб форм, которая предоставляет все эти, и многие другие, возможности для действительно сложных сценариев.
Установка
В приложениях, использующих Symfony Flex, запустите эту команду, чтобы установить функцию формы перед её использованием:
1
$ composer require symfony/form
Использование
Рекомендованный рабочий процесс при работе с формами Symfony, следующий:
- Создайте форму в контроллере Symfony или используя cпециальный класс формы;
- Отобразите форму в шаблоне, чтобы пользователь мог редактировать и отправлять ее;
- Обработайте форму, чтобы валидировать отправленные данные, преобразовать их в PHP-данные и сделать что-то с ними (например, сохранить в базе данных).
Каждый из этих шагов подробно разъясняется в следующих разделах. Чтобы сделать примеры более простыми для понимания, все из них предполагают, что вы создаете небольшое приложение списка дел, отображающее "задачи".
Пользователи создают и редактируют задачи используя формы Symfony. Каждая задача - это экземпляр
следующего класса Task
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
// src/Entity/Task.php
namespace App\Entity;
class Task
{
protected string $task;
protected ?\DateTimeInterface $dueDate;
public function getTask(): string
{
return $this->task;
}
public function setTask(string $task): void
{
$this->task = $task;
}
public function getDueDate(): ?\DateTimeInterface
{
return $this->dueDate;
}
public function setDueDate(?\DateTimeInterface $dueDate): void
{
$this->dueDate = $dueDate;
}
}
Этот класс представляет собой обычный PHP-объект, так как на данный момент он не имеет ничего общего с Symfony или какой-либо другой библиотекой. Это обычный PHP-объект, который выполняет задачу непосредственно внутри вашего приложения (т.е. необходимость представления задачи в вашем приложении). Но вы можете редактировать сущности Doctrine таким же образом.
Типы форм
Прежде чем создавать свою первую форму Symfony, важно понимать концепцию "типа формы". В других проектах часто различают "формы" и "поля формы". В Symfony же все это - "типы формы":
- одно поле формы
<input type="text">
- это "тип формы" (например,TextType
); - группа нескольких HTML-полей, используемая для ввода почтового адреса - это "тип формы"
(например,
PostalAddressType
); - целая
<form>
с множеством полей для редактирования профиля пользователя - это "тип формы" (например,UserProfileType
).
Вначале это может показаться запутанным, но вскоре станет естественным. Кроме того, это упрощает код и делает "компоновку" и "встраивание" полей формы намного проще в реализации.
Существуют десятки типов формы, предоставленных Symfony и вы также можете создавать собственные типы формы.
Tip
Вы можете использовать debug:form
, чтобы перечислить все доступные типы,
расширения типов и угадыватели типов в вашем приложении:
1 2 3 4 5 6 7 8
$ php bin/console debug:form
# передать FQCN типа формы, чтобы отобразить только опции для этого типа, его родителей и расширения.
# Для встроенных типов вы можете передать короткое имя класса вместо FQCN
$ php bin/console debug:form BirthdayType
# также передать имя опции, чтобы отобразить только полное определение этой опции
$ php bin/console debug:form BirthdayType label_attr
Построение форм
Symfony предоставляет объект "конструктора формы", который позволяет вам описывать поля формы, используя свободный интерфейс. Позже, этот конструктор создает реальный объект формы, используемый для отображения и обработки содержания.
Создание формы в контроллере
Если ваш контроллер расширяется из AbstractController ,
используйте помощник createFormBuilder()
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
// src/Controller/TaskController.php
namespace App\Controller;
use App\Entity\Task;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class TaskController extends AbstractController
{
public function new(Request $request): Response
{
// создаёт объект задачи и инициализирует некоторые данные для этого примера
$task = new Task();
$task->setTask('Write a blog post');
$task->setDueDate(new \DateTime('tomorrow'));
$form = $this->createFormBuilder($task)
->add('task', TextType::class)
->add('dueDate', DateType::class)
->add('save', SubmitType::class, ['label' => 'Create Task'])
->getForm();
// ...
}
}
Если ваш контроллер не расширяется из AbstractController
, вам нужно будет
получить сервисы в вашем контроллере и
использовать метод createBuilder()
сервиса form.factory
.
В этом примере вы добавили к вашей форме 2 поля - task
и dueDate
- соответствующих свойствам task
и dueDate
класса Task
. Вы уже
каждому тип формы (например, TextType
и DateType
),
представленных их полным именем класса. Наконец, вы добавили кнопку отправки с
пользовательским ярлыкм, для отправи формы серверу.
Создание классов формы
Symfony рекомендует размещать минимально возможное количество логики в контроллерах. Вот почему лучше перемещать сложные формы в посвященные им классы, вместо того, чтобы определять их в действиях контроллера. Кроме того, формы, определенные в классах, могут быть использованы повторно в нескольких действиях и сервисах.
Классы формы - это типы формы , которые реализуют FormTypeInterface. Однако, лучше расширять из AbstractType, который уже реализует интерфейс и предоставляет некоторые утилиты:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
// src/Form/Type/TaskType.php
namespace App\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
class TaskType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('task', TextType::class)
->add('dueDate', DateType::class)
->add('save', SubmitType::class)
;
}
}
Tip
Установите в своем проекте MakerBundle, чтобы генерировать классы формы
используя команды make:form
и make:registration-form
.
Класс формы содержит все необходимые инструкции для создания формы задач. В контроллерах,
расширяющихся из AbstractController ,
используйте помощник createForm()
(в других случаях используйте create()
, метод
сервиса form.factory
):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
// src/Controller/TaskController.php
namespace App\Controller;
use App\Form\Type\TaskType;
// ...
class TaskController extends AbstractController
{
public function new(): Response
{
// создаёт объект задачи и инициализирует некоторые данные для этого примера
$task = new Task();
$task->setTask('Write a blog post');
$task->setDueDate(new \DateTime('tomorrow'));
$form = $this->createForm(TaskType::class, $task);
// ...
}
}
Каждая форма должна знать имя класса, содержащего основополагающие данные
(например, App\Entity\Task
). Обычно, это угадывается на основе объекта,
переданного второму аргементу к createForm()
(т.е. $task
).
Позже, когда вы начнете встраивать формы, этого уже не
будет достаточно.
Поэтому, хотя это и не всегда необходимо, обычно хорошей идеей будет яdно указать
опцию data_class
, добавив следующее к вашему классу типа формы:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
// src/Form/Type/TaskType.php
namespace App\Form\Type;
use App\Entity\Task;
use Symfony\Component\OptionsResolver\OptionsResolver;
// ...
class TaskType extends AbstractType
{
// ...
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => Task::class,
]);
}
}
Отображение формы
Теперь, когда форма была создана, следующий шаг - отобразить ее. Вместо того,
чтобы передавать весь объект формы шаблону, используйте метод createView()
,
чтобы построить другей объект с визуальным представлением формы:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
// src/Controller/TaskController.php
namespace App\Controller;
use App\Entity\Task;
use App\Form\Type\TaskType;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class TaskController extends AbstractController
{
public function new(Request $request): Response
{
$task = new Task();
// ...
$form = $this->createForm(TaskType::class, $task);
return $this->render('task/new.html.twig', [
'form' => $form,
]);
}
}
Внутренне, метод render()
вызывает $form->createView()
, чтобы
преобразовать форму в экземпляр просмотра формы.
Затем, используйте некоторые функции-помощники формы, чтобы отобразить содержание формы:
1 2
{# templates/task/new.html.twig #}
{{ form(form) }}
Вот и всё! Функция form() отображает все
поля и стартовые и конечные теги <form>
. По умолчанию, метод формы -
POST
и целевой URL такой же, который отображал форму, но
вы можете изменить оба этих пункта .
Заметьте, как отображенное поле ввода task
имеет значение свойства task
из
объекта $task
(т.е. "Написать пост в блоге"). Это первая задача формы: брать
данные из объекта и переводить их в формат, подходящий для отображения в HTML-форме.
Tip
Система форм достаточно умна, чтобы получить доступ к значению защищенного
свойства task
через методы getTask()
и setTask()
класса Task
.
Кром случаев, когда свойство публично, оно должно иметь методы "getter" и
"setter", чтобы Symfony могла получать и размещать данные в свойстве. Для булевого
свойства, вы можете использовать метод "isser" или "hasser" (например, isPublished()
или hasReminder()
) вместо геттера (например, getPublished()
или getReminder()
).
Несмотря на то, что это отображение короткое, оно не очень гибкое. Обычно вам нужно будет иметь больше контроля над тем, как выглядит вся форма или некоторые ее поля. Например, благодаря интеграции Bootstrap 5 с формами Symfony, вы можете установить эту опцию, чтобы сгенерировать формы, совместимые с CSS-фреймворком Bootstrap 4:
1 2 3
# config/packages/twig.yaml
twig:
form_themes: ['bootstrap_5_layout.html.twig']
Встроенные темы формы Symfony включают в себя Bootstrap 3, 4 и 5 а также Foundation 5 и 6, и Tailwind 2. Вы также можете создать собственную тему формы Symfony .
В дополнение к темам формы, Symfony позволяет вам настраивать то, как отображаются поля со множеством функций для отображения каждой части поля отдельно (виджеты, ярлыки, ошибки, сообщения помощи, и т.д.)
Обработка формы
Рекомендованный способ обработки формы - это использование действия как для отображения формы, так и для обработки ее отправки. Вы можете использовать отдельные действия, но использование одного все упрощает и в то же время делает код компактным и легко изменяемым.
Обработка формы означает перевод данных, отправленных пользователем, в свойства объекта. Чтобы это произошло, отправленные данные пользователя должны быть записаны в объект формы:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
// src/Controller/TaskController.php
// ...
use Symfony\Component\HttpFoundation\Request;
class TaskController extends AbstractController
{
public function new(Request $request): Response
{
// просто настройте свежий объект $task (удалите данные примера)
$task = new Task();
$form = $this->createForm(TaskType::class, $task);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// $form->getData() holds the submitted values
// но изначальная переменная `$task` также была обновлена
$task = $form->getData();
// ... выполните какое-то действие, например сохраните задачу в базу данных
// for example, if Task is a Doctrine entity, save it!
// $entityManager = $this->getDoctrine()->getManager();
// $entityManager->persist($task);
// $entityManager->flush();
return $this->redirectToRoute('task_success');
}
return $this->renderForm('task/new.html.twig', [
'form' => $form,
]);
}
}
Контроллер следует общему паттерну для обработки форм, и имеет три возможных пути:
- При изначальной загрузке страницы в браузере, форма еще не была отправлена,
и
$form->isSubmitted()
возвращаетfalse
. Таким образом, форма создается и отображается; Когда пользователь отправляет форму, handleRequest() распознает это и немедленно пишет отправленные данные обратно в свойства
task
иdueDate
объекта$task
. Затем этот объект валидируется (валидация разъясняется в следующем разделе). Если он не валиден, isValid() возвращаетfalse
и форма отображается снова, но теперь с ошибками валидации;При передаче
$form
методуrender()
(вместо$form->createView()
), код ответа автоматически устанавливается как HTTP 422 Необрабатываемое содержание. Это гарантирует совместимость с интрументами, которые полагаются на спецификацию HTTP, вроде Symfony UX Turbo;- Когда пользователь отправляет форму с валидыми данными, отправленные данные
снова записываются в форму, но в этот раз isValid()
возвращает
true
. Теперь у вас есть возможность выполнить какие-то действия, используя объект$task
(например, сохранение в базу данных), прежде чем перенаправлять пользователя на какую-то другую страницу (например, страницу "спасибо" или "успешно");
Note
Перенаправление пользователя после успешной отправки формы - лучшая практика, которая предотвращает пользователя от нажатия кнопки "Обновить" в их браузере и повторной отправки данных.
See also
Если вам нужно больше контроля над тем, как ваша форма отпавляется, или какие данные передаются ей, вы можете использовать метод submit() для обработки отправки формы.
Валидация формы
В предыдущем разделе вы узнали, как форма может быть отправлена с валидными
или не валидными данными. В Symfony валидация применяется к объекту, лежащему
в основе формы (например, Task
). Другими словами, вопрос не в том, валидна
ли «форма», а валиден ли объект $task
, после того как форма передала ему
отправленные данные. Вызов метода $form->isValid()
– это сокращение, которое
спрашивает объект $task
валидны ваши данные или нет.
До использования валидации, добавьте её поддержку в ваше приложение:
1
$ composer require symfony/validator
Валидация проводится путем добавления к классу набора правил, под названием (валидация) ограничения. Вы можете добавить их либо к классу сущности, либо используя опцию ограничений типов формы.
Чтобы увидеть первый подход - добавление ограничений к сущности - в действии,
добавьте ограничения валидации, так, чтобы поля task
и dueDate
не могли
быть пустыми, и последнее было валидным объектом DateTime
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// src/Entity/Task.php
namespace App\Entity;
use Symfony\Component\Validator\Constraints as Assert;
class Task
{
#[Assert\NotBlank]
public string $task;
#[Assert\NotBlank]
#[Assert\Type(\DateTimeInterface::class)]
protected \DateTimeInterface $dueDate;
}
Это всё! Если вы повторно отправите форму с не валидными данными, вы увидите, что соответствующие ошибки будут отображены в форме.
Чтобы увидеть второй подход - добавление ограничений к форме - и чтобы узнать больше об ограничениях валидации, пожалуйста, обратитесь к документации валидации Symfony.
Другие распространённые функции формы
Передача опций форме
Если вы создаете формы в классах , при создании формы в
контроллере, вы можете передать ей пользовательсткие опции в качестве третьего необязательного
аргумента createForm()
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
// src/Controller/TaskController.php
namespace App\Controller;
use App\Form\Type\TaskType;
// ...
class TaskController extends AbstractController
{
public function new(): Response
{
$task = new Task();
// используйте некоторую PHP-логику, чтобы решить, обязательно ли это поле формы
$dueDateIsRequired = ...;
$form = $this->createForm(TaskType::class, $task, [
'require_due_date' => $dueDateIsRequired,
]);
// ...
}
}
Если вы попробуете использовать форму сейчас, вы увидите сообщение об ошибке:
Опция "require_due_date" не существует. Это потому что формы должны заявлять
обо всех опциях, которые они принимают, используя метод configureOptions()
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
// src/Form/Type/TaskType.php
namespace App\Form\Type;
use Symfony\Component\OptionsResolver\OptionsResolver;
// ...
class TaskType extends AbstractType
{
// ...
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
// ...,
'require_due_date' => false,
]);
// вы также можете определить позволенные типы, значения и
// любые другие функции, поддерживающиеся компонентом OptionsResolver
$resolver->setAllowedTypes('require_due_date', 'bool');
}
}
Теперь вы можете использовать эту новую опцию формы внутри метода buildForm()
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
// src/Form/Type/TaskType.php
namespace App\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\FormBuilderInterface;
class TaskType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
// ...
->add('dueDate', DateType::class, [
'required' => $options['require_due_date'],
])
;
}
// ...
}
Опции типа формы
Каждый тип формы имеет ряд опций для его конфигурации, как объясняется
в справочнике типов формы Symfony. Две наиболее ипользуемые
опции - это required
и label
.
Опция required
Наиболее распространенной опцией является required
, которая может прменяться к любому
полю. По умолчанию, эта опция установлена как true
, что означает, что готовые к HTML5
браузеры будут требовать заполнения всех полей перед отправкой формы.
Если вы не хотите такого поведения, то либо
отключите валидацию клиентской стороны для всей формы,
либо установите опцию required
как false
в одном или более полях:
1 2 3
->add('dueDate', DateType::class, [
'required' => false,
])
Опция required
не выполняет валидацию серверской стороны. Если пользователь отправляет
пустое значение поля (либо в старом браузере, либо веб-сервисе, к примеру), оно будет
принято как валидное значение, разве что вы также не используете ограничения валидации
Symfony NotBlank
или NotNull
.
Опция label
По умолчанию, ярлык полей формы - это очеловеченная версия имени свойства
(user
-> User
; postalAddress
-> Postal Address
).
Установите опцию label
в полях, чтобы явно определить их ярлыки:
1 2 3 4
->add('dueDate', DateType::class, [
// установите как FALSE, чтобы не отображать ярлык для этого поля
'label' => 'To Be Completed Before',
])
Tip
По умолчанию, теги <label>
обязательных полей отображаются с CSS-классом
required
, поэтому вы можете отобразить звездочку, применив CSS-стиль:
1 2 3
label.required:before {
content: "*";
}
Изменение действия и HTTP-метода
По умолчанию, форма будет отправлена через запрос HTTP POST по тому же URL,
под которым отображалась форма. При создании формы в контроллере, используйте
методы setAction()
и setMethod()
, чтобы изменить это:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
// src/Controller/TaskController.php
namespace App\Controller;
// ...
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
class TaskController extends AbstractController
{
public function new(): Response
{
// ...
$form = $this->createFormBuilder($task)
->setAction($this->generateUrl('target_route'))
->setMethod('GET')
// ...
->getForm();
// ...
}
}
При создании формы в классе, передайте действие и метод в виде опций формы:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
// src/Controller/TaskController.php
namespace App\Controller;
use App\Form\TaskType;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
// ...
class TaskController extends AbstractController
{
public function new(): Response
{
// ...
$form = $this->createForm(TaskType::class, $task, [
'action' => $this->generateUrl('target_route'),
'method' => 'GET',
]);
// ...
}
}
Наконец, вы можете пеоепределить действие в шаблоне, передав их функциям помощников
form()
или form_start()
:
1 2
{# templates/task/new.html.twig #}
{{ form_start(form, {'action': path('target_route'), 'method': 'GET'}) }}
Note
Если метод формы не GET
или POST
, а PUT
, PATCH
или
DELETE
, Symfony внедрит скрытое поле с именем _method
, которое
хранит этот метод. Форма будет отправлена в нормальнои запросе POST
,
но маршрутизация Symfony способна обнаружить параметр
_method
и будет интерпретировать его как запрос PUT
, PATCH
или
DELETE
. Опция должна
быть включена, чтобы это работало.
Изменение имени формы
Если вы исследуете HTML-содержание отображенной формы, вы увидите, что имя
<form>
и имена полей генерируются из имени класса типа
(например, <form name="task" ...>
и <select name="task[dueDate][date][month]" ...>
).
Если вы хотите изменить это, используйте метод createNamed():
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
// src/Controller/TaskController.php
namespace App\Controller;
use App\Form\TaskType;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\FormFactoryInterface;
// ...
class TaskController extends AbstractController
{
public function new(FormFactoryInterface $formFactory): Response
{
$task = ...;
$form = $formFactory->createNamed('my_name', TaskType::class, $task);
// ...
}
}
Вы даже можете полностью подавить имя, установив пустую строку.
HTML-валидация клиентской стороны
Благодаря HTML5, многие браузеры могут нативно устанавливать определенные ограничения
валидации клиентской стороны. Наиболее распространенная валидация активируется путем
добавления атрибута required
в обязательные поля. Для браузеров, поддерживающих
HTML5, это приведет к отображению родного сообщения браузера, если пользователь попробует
отправить форму с таким пустым полем.
Сгенерированные формы вовсю пользуются этой новой фнукцией, добавляя правильные
HTML-атрибуты, которые триггерят валидацию. Валидация клиентской стороны, однако,
может быть отключена, путем добавления атрибута novalidate
к тегу <form>
или
formnovalidate
к тегу отправки. Это особенно полезно, если вы хотите протестировать
ограничения валидации клиентское стороны, но ваш браузер не позволяет вам, к примеру,
отправить пустые поля.
1 2 3 4
{# templates/task/new.html.twig #}
{{ form_start(form, {'attr': {'novalidate': 'novalidate'}}) }}
{{ form_widget(form) }}
{{ form_end(form) }}
Угадывание типа формы
Если объект, обрабатываемый формой, имеет ограничения валидации, Symfony может
исследовать мтеоды, чтобы угадать типа вашего поля и настроить его для вас. В
примере выше, Symfony может угадать по правилам валидации, что поле task
- это
нормальное поле TextType
, а поле dueDate
- это поле DateType
.
При создании формы, опустите второй аргумент метода add()
, или передайте
ему null
, чтобы включить "механизм угадывания" Symfony:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
// src/Form/Type/TaskType.php
namespace App\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
class TaskType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
// если вы не определите опции поля, вы можете опустить второй аргумент
->add('task')
// если вы определите опции поля, передайте NULL в качестве второго аргумента
->add('dueDate', null, ['required' => false])
->add('save', SubmitType::class)
;
}
}
Caution
При использовании определенной группы валидации формы, угадыватель типа поля начнет рассматривать все ограничения валидации при угадывании типов ваших полей (включая ограничения, которые не являются частью используемых(ой) групп(ы) валидации).
Угадывание опций типа формы
Когда для какого-то поля включены механизмы угадывания (т.е. вы опускаете или
передаете null
в качестве второго аргумента add()
), в дополнение к типу
формы, могут быть угаданы следующие опции:
required
-
Опция
required
может быть угадана на основании правил валидации (т.е. является ли полеNotBlank
илиNotNull
) или метаданных Doctrine (т.е. является ли полеnullable
). Это очень полезно, так как валидация вашей клиентской стороны будет автоматически соответствовать вашим правилам валидации. maxlength
-
Если поле является некоторым видом текстового поля, то может быть угадан атрибут
опции
maxlength
из ограничений валидации (используется лиLength
илиRange
) или из метаданных Doctrine (через длину поля).
Если вы хотите изменить одно из угаданных значений, переопределите его, передав опцию в массиве опций поля:
1
->add('task', null, ['attr' => ['maxlength' => 4]])
See also
Кроме угадывания типа формы, Symfony также угадывает ограничения валидации если вы используете сущность Doctrine. Прочтите руководство , чтобы узнать больше информации.
Неотображённые поля
При редактировании объекта через форму, все поля формы считаются свойствами объекта. Любые поля формы, не существующие в объекте, будут вызывать исключения.
Если вам нужны дополнительные поля в форме, которые не будут храниться в объекте
(например, чтобы добавить флажок "Я согласен с этими условями" checkbox), установите
опцию как false
в этих полях:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
// ...
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormBuilderInterface;
class TaskType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('task')
->add('dueDate')
->add('agreeTerms', CheckboxType::class, ['mapped' => false])
->add('save', SubmitType::class)
;
}
}
Эти "неотображенные поля" могут быть установлены и доступны в контроллере с помощью:
1 2
$form->get('agreeTerms')->getData();
$form->get('agreeTerms')->setData(true);
Кроме того, если в форме есть поля, которые не добавлены в отправленные данные,
эти поля будут явно установлены как null
.
Узнайте больше
При создании форм, помните, что первоочередной целью формы является перевод
данных из объекта (Task
) в HTML-форму, чтобы пользователь мог изменять эти
данные. Вторая цель формы - взять данные, отправленные пользователем, и повторно
применить их к объекту.
В формах Symfony существует еще очень много всего, что можно узнать, и множество мощных фокусов:
Справочник:
Продвинутые функции:
- Как загружать файлы
- Как реализовать CSRF-защиту
- Как получить доступ к сервисам или конфигурации изнутри формы
- Как создать пользовательский тип поля формы
- Как использовать преобразователи данных
- Как и когда использовать отображатели данных
- Как создать расширение типа формы
- Создание пользовательского отгадывателя типа
Темы формы и настройка:
События:
Валидация:
Разное:
- Как использовать функцию submit() для обработки отправки форм
- Как встраивать формы
- Как встроить коллекцию форм
- Как уменьшить дублирование кода с помощью "inherit_data"
- Как отправить форму с несколькими кнопками
- Как проводить модульное тестирование ваших форм
- Как сконфигурировать пустые данные для класса формы
- Как использовать форму без класса данных