Programmation PHP avec Symfony/Formulaire
Principe
Le principe est d'ajouter des champs de formulaire en PHP, qui seront automatiquement convertis en code HTML correspondant.
En effet, comme vu dans le [[../../Formulaire|chapitre sur les formulaire PHP]], en HTML on utilise habituellement la balise <form>
pour afficher les champs à remplir par le visiteur. Puis sur validation on récupère leurs valeurs en PHP avec la superglobale $_REQUEST
(ou ses composantes $_GET
et $_POST
). Or ce système ne fonctionne pas en $_POST
dans Symfony : si on affiche un tel formulaire et qu'on le valide, $_POST
est vide, et l'équivalent Symfony de $_REQUEST
, $request->request
[1] aussi.
Les formulaires doivent donc nécessairement être préparés en PHP.
Installation
composer require symfony/form
Pour ajouter des contrôles sur les champs[2] :
composer require symfony/validator
Contrôleur
Injection du formulaire dans un Twig
class HelloWorldController extends AbstractController
{
/**
* @Route("/helloWorld", name="helloWorld")
*
* @return Response
*/
public function indexAction(Request $request)
{
$form = $this->createForm(HelloWorldForm::class);
return $this->render('helloWorld.html.twig', [
'form' => $form->createView(),
]);
}
}
Le second paramètre de createForm() est facultatif est sert à préciser des valeurs initiales dans le formulaire qui seront injectées en Twig, mais elles peuvent aussi l'être via le fichier du formulaire dans les paramètres de chaque champ.
Traitement post-validation
Dans la même méthode du contrôleur qui injecte le formulaire, il faut prévoir le traitement post-validation :
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$email = $form->get('email')->getData();
// ...
}
Fichier du formulaire
Dans SF4, l'espace de nom Symfony\Component\Form\Extension\Core\Type propose 35 types de champ, tels que :
- email (avec validation en option de la présence d'arrobase ou de domaine).
- submit (bouton).
- date.
Exemple[3] :
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('email', 'text', [
'required' => true,
'empty_data' => 'valeur par défaut',
'constraints' => [new Assert\NotBlank()],
'attr' => ['class' => 'ma_classe_CSS'],
]);
}
Pour préremplir des valeurs dans les champs :
$form->get('email')->setData($user->getEmail());
EntityType
De plus, en installant Doctrine, il est possible d'ajouter un type de champ "entité" directement relié avec un champ de base de données[4].
Il n'y a pas de type Checkbox ou Radiobox comme mais il faut jouer sur deux paramètres de EntityType
ainsi :
Élément | Expanded | Multiple |
---|---|---|
Sélecteur | false | false |
Sélecteur multiple | false | true |
Boutons radio | true | false |
Cases à cocher | true | true |
Exemple :
$builder->add('gender', EntityType::class, ['expanded' => true, 'multiple' => false]);
Contrôle
Le validateur de formulaire d'entité peut utiliser les annotations des entités. Ex :
use Symfony\Component\Validator\Constraints as Assert;
...
/**
* @Assert\NotBlank
* @Assert\Type("string")
*/
Sinon il permet aussi des contrôles plus personnalisés dans les types (qui étendent Symfony\Component\Form\AbstractType). Ex :
'constraints' => [
new Assert\NotBlank(),
new Assert\Callback([ProductChecker::class, 'check']),
],
Plusieurs types de données sont déjà définis, comme l'email ou l'URL[5]. Ex :
@Assert\Email()
Appel du formulaire Symfony dans la vue
Les fonctions Twig permettant d'ajouter les éléments du formulaire sont :
- form_start
- form_errors
- form_row
- form_widget
- form_label
Pour afficher tout le formulaire, dans l'ordre où les champs ont été définis en PHP :
{{ form_start(form) }}
{{ form_end(form) }}
Pour n'afficher qu'un seul champ :
{{ form_widget(form.choosen_credit_card) }}
Les même attributs qu'en PHP peuvent être définis en paramètre. Ex :
{{ form_widget(form.name, {'attr': {'class': 'address', 'placeholder': 'Entrer une adresse'} }) }}
{{ form_label(form.name, null, {'label_attr': {'class': 'address'}}) }}
Exemple complet :
{{ form_start(form) }}
{{ form_errors(form) }}
{{ form_label(form.name, 'Label du champ "name" écrasé ici') }}
{{ form_row(form.name) }}
{{ form_widget(form.message, {'attr': {'placeholder': 'Remplacez ce texte par votre message'} }) }}
{{ form_rest(form) }}
{{ form_row(form.submit, { 'label': 'Submit me' }) }}
{{ form_end(form) }}
Références
- ↑ https://symfony.com/doc/current/components/http_foundation.html
- ↑ https://symfony.com/doc/current/forms.html#form-validation
- ↑ https://symfony.com/doc/current/reference/forms/types/form.html#empty-data
- ↑ https://symfony.com/doc/master/reference/forms/types/entity.html
- ↑ https://symfony.com/doc/current/validation.html#string-constraints