Як викоритовувати форму без класу даних

Дата оновлення перекладу 2022-11-20

Як викоритовувати форму без класу даних

У більшості випадків, форма привʼязана до обʼєкта, а поля форми отримують та зберігають свої дані у властивостях цього обʼєкта. Це саме те, що ви бачили до цього часу у статті з класом Task.

Але іноді вам може знадобитися використати форму без класу і отримати назад масив відправлених даних. Метод getData() дозволяє вам робити саме це:

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
// src/Controller/ContactController.php
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
// ...

class ContactController extends AbstractController
{
    public function contact(Request $request): Response
    {
        $defaultData = ['message' => 'Type your message here'];
        $form = $this->createFormBuilder($defaultData)
            ->add('name', TextType::class)
            ->add('email', EmailType::class)
            ->add('message', TextareaType::class)
            ->add('send', SubmitType::class)
            ->getForm();

        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            // дані - це масив з ключами "name", "email", і "message"
            $data = $form->getData();
        }

        // ... відобразити форму
    }
}

За замовчуванням, форма насправді припускає, що ви хочете працювати з масивами даних, замість обʼєкта. Існує рівно два способи, щоб змінити цю поведінку та привʼязати форму до обʼєкта:

  1. Передати обʼєкт при створенні форми (в якості першого аргументу createFormBuilder() або другого аргументу createForm());
  2. Оголосити у вашій формі опцію data_class.

Якщо ви не зробите нічого з цього, тоді форма буде повертати дані у вигляді масиву. У цьому прикладі, так як $defaultData - це не обʼєкт (і не встановлена опція data_class), $form->getData() в кінцевому рахунку повертає масив.

Tip

Ви також можете отримати доступ до значень POST (у цьому випадку - "name") напряму через обʼєкт запиту, ось так:

1
$request->request->get('name');

Але майте на увазі, що у більшості випадків, використання методу getData() буде краще, так як він повертає дані (зазвичай у вигляді обʼєкта) після того, як вони були перетворені компонентом Форма.

Додавання валідації

Єдиним відсутнім елементом є валідація. Зазвичай, коли ви викликаєте $form->handleRequest($request), обʼєкт валідується шляхом зчитування обмежень, які ви застосували до цього класу. Якщо ваша форма привʼязана до обʼєкта (тобто, ви використовуєте опцію data_class або передаєте обʼєкт у вашу форму), то ви захочете використовувати цей підхід майже завжди. Дивіться Валідація, щоб дізнатися більше.

Але якщо форма не привʼязана до обʼєкта, і ви хочете отримати простий масив ваших відправлених даних, як ви можете додати обмеження до даних вашої форми?

Відповідь - встановити обмеження самостійно та приєднати їх до індивідуальних полів. Цей підхід детальніше розглядається у цій статті про валідацію, але ось короткий приклад:

use SymfonyComponentFormExtensionCoreTypeTextType; use SymfonyComponentFormFormBuilderInterface; use SymfonyComponentValidatorConstraintsLength; use SymfonyComponentValidatorConstraintsNotBlank;

public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('firstName', TextType::class, [ 'constraints' => new Length(['min' => 3]), ]) ->add('lastName', TextType::class, [ 'constraints' => [ new NotBlank(), new Length(['min' => 3]), ], ]) ; }

Tip

Якщо ви використовуєте групи валідації, вам потрібно або послатися на групу Default при створенні форми, або встановити правильну групу в обмеженні, яке ви додаєте.

new NotBlank(['groups' => ['create', 'update']]);

Tip

Якщо форрма не привʼязана до обʼєкта, то кожний обʼєкт у вашому масиві відправлених даних валідується з використанням обмеження Symfony\Component\Validator\Constraints\Valid, окрім випадків, коли ви відключаєте валідацію.

Caution

Коли форма відправлена лише частково (наприклад, в HTTP-запиті PATCH), лише обмеження з відправлених полів форми будуть оцінені.