Как использовать форму без класса данных

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

Но иногда вам может быть нужно использовать форму без класса, и получить обратно массив отправленных данных. Это на самом деле очень просто:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// убедитесь, что вы испортировали пространство имён Request над классом
use Symfony\Component\HttpFoundation\Request;
// ...

public function contactAction(Request $request)
{
    $defaultData = array('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->isValid(), объект валидируется путём считывания ограничений, которые вы применили к этому классу. Если ваша форма привязана к объекту (т.е. вы используете опцию data_class или передаёте объект в вашу форму), то вы захотите использовать этот подход практически всегда. Смотрите Validation, чтобы узнать больше.

Но если форма не привязана к объекту, и вы хотите получить простой массив ваших отправленных данных, как вы можете добавить ограничения к данным вашей формы?

Ответ - установить ограничения самостоятельно и присоединить их к индивидуальным полям. Этот подход детальнее рассматривается в этой статье о валидации, но вот краткий пример:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
use Symfony\Component\Validator\Constraints\Length;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Form\Extension\Core\Type\TextType;

$builder
   ->add('firstName', TextType::class, array(
       'constraints' => new Length(array('min' => 3)),
   ))
   ->add('lastName', TextType::class, array(
       'constraints' => array(
           new NotBlank(),
           new Length(array('min' => 3)),
       ),
   ))
;

Tip

Если вы используете группы валидации, вам нужно либо сослаться на группу Default при создании формы, или установить правильную группу в ограничении, которое вы добавляете.

1
new NotBlank(array('groups' => array('create', 'update')));

Tip

Если форма не привязана к объекту, то каждый объект в вашем массиве отправленных данных валидируется с использованием ограничения Symfony\Component\Validator\Constraints\Valid, кроме случаев, когда вы отключаете валидацию.

Эта документация является переводом официальной документации Symfony и предоставляется по свободной лицензии CC BY-SA 3.0.