formulaire


Pour un développeur Web, le traitement des formulaires HTML est l'une des tâches les plus courantes et les plus difficiles. Symfony intègre un composant Form pour faciliter le traitement des formulaires. Dans ce chapitre, vous créerez un formulaire complexe à partir de zéro et découvrirez les fonctionnalités importantes de la bibliothèque de formulaires.

Le composant Form de Symfony est une bibliothèque de classes indépendante que vous pouvez utiliser en dehors de votre projet Symfony. Reportez-vous à la Documentation du composant Form pour en savoir plus.

Créez un formulaire simple

Supposons que vous construisiez une simple liste de tâches pour afficher certaines "tâches". Vous devez créer un formulaire pour permettre à vos utilisateurs de modifier et de créer des tâches. Avant cela, jetons un coup d'œil à la classe Task, qui peut restituer et stocker des données pour une seule tâche. Task 类,它可呈现和存储一个单一任务的数据。

// src/AppBundle/Entity/Task.phpnamespace AppBundle\Entity; class Task{
    protected $task;
    protected $dueDate;     public function getTask()
    {
        return $this->task;
    }     public function setTask($task)
    {
        $this->task = $task;
    }     public function getDueDate()
    {
        return $this->dueDate;
    }     public function setDueDate(\DateTime $dueDate = null)
    {
        $this->dueDate = $dueDate;
    }}

这是一个原生的PHP对象类,因为它没有和Symfony互动也没有引用其它类库。它是非常简单的一个PHP对象类,直接解决了 程序中的 task (任务)之数据问题。当然,在本章的最后,你将能够通过HTML表单把数据提交到一个 Task 实例,验证它的值,并把它持久化到数据库。

构建表单 

现在你已经创建了一个 Task

// src/AppBundle/Controller/DefaultController.phpnamespace AppBundle\Controller; use AppBundle\Entity\Task;use Symfony\Bundle\FrameworkBundle\Controller\Controller;use Symfony\Component\HttpFoundation\Request;use Symfony\Component\Form\Extension\Core\Type\TextType;use Symfony\Component\Form\Extension\Core\Type\DateType;use Symfony\Component\Form\Extension\Core\Type\SubmitType; class DefaultController extends Controller{
    public function newAction(Request $request)
    {
        // create a task and give it some dummy data for this example
        // 创建一个task对象,赋一些例程中的假数据给它
        $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, array('label' => 'Create Task'))
            ->getForm();         return $this->render('default/new.html.twig', array(
            'form' => $form->createView(),
        ));
    }}

Il s'agit d'une classe d'objet PHP native, car elle n'interagit pas avec Symfony et ne fait pas référence à d'autres bibliothèques. Il s'agit d'une classe d'objets PHP très simple qui résout directement le problème de données de task (tâche) dans votre programme. Bien entendu, à la fin de ce chapitre, vous serez en mesure de soumettre des données à une instance Task via un formulaire HTML, de valider sa valeur et de la conserver dans une base de données.

Créez le formulaire

Cet exemple montre comment créer votre formulaire directement dans le contrôleur. Plus loin dans 🎜Création d'une classe de formulaire🎜, vous utiliserez une classe distincte pour créer le formulaire. Cette méthode est recommandée car le formulaire peut être réutilisé. 🎜🎜

Créer un formulaire ne nécessite pas beaucoup de code car les objets de formulaire Symfony sont créés via un « générateur de formulaire ». Le but du générateur de formulaire est de vous permettre d'écrire des "instructions" simples pour la création d'un formulaire, et toutes les tâches de "surcharge" lors de la création réelle du formulaire sont effectuées par le générateur.

Dans cet exemple, vous avez ajouté deux champs au formulaire, à savoir task et dueDate. Correspondant aux attributs task et dueDate de la classe Task. Vous avez spécifié le "type" de FQCN (nom de classe complet/nom de classe de chemin complet) pour eux respectivement (tel que TextType, DateType), qui est déterminé par le tapez à générer pour le champ. Quelle balise de formulaire HTML (groupe de balises). taskdueDate 。对应的是 Task 类中的 taskdueDate 属性。你已为它们分别指定了FQCN(Full Quilified Class Name/完整路径类名)的“类型”(如 TextTypeDateType ),由类型决定为字段生成哪一种HTML表单标签(标签组)。

最后,你添加了一个带有自定义label的提交按钮以向服务器提交表单。

Symfony附带了许多内置类型,它们将被简短地介绍(见下面的内置表单类型)。

渲染表单 

表单创建之后,下一步就是渲染它。这是通过传递一个特定的表单“view”对象(注意上例控制器中的  $form->createView() 方法)到你的模板,并通过一系列的表单helper function(帮助函数)来实现的。

PHP:<!-- app/Resources/views/default/new.html.php -->
<?php echo $view['form']->start($form) ?>
<?php echo $view['form']->widget($form) ?>
<?php echo $view['form']->end($form) ?>
// ...use Symfony\Component\HttpFoundation\Request; public function newAction(Request $request){
    // just setup a fresh $task object (remove the dummy data)
    // 直接设置一个全新$task对象(删除了假数据)
    $task = new Task();     $form = $this->createFormBuilder($task)
        ->add('task', TextType::class)
        ->add('dueDate', DateType::class)
        ->add('save', SubmitType::class, array('label' => 'Create Task'))
        ->getForm();     $form->handleRequest($request);     if ($form->isSubmitted() && $form->isValid()) {         // $form->getData() holds the submitted values
        // but, the original `$task` variable has also been updated
        //  $form->getData() 持有提交过来的值
        // 但是,原始的 `$task` 变量也已被更新了
        $task = $form->getData();         // ... perform some action, such as saving the task to the database
        // for example, if Task is a Doctrine entity, save it!
        // 一些操作,比如把任务存到数据库中
        // 例如,如果Tast对象是一个Doctrine entity,存下它!
        // $em = $this->getDoctrine()->getManager();
        // $em->persist($task);
        // $em->flush();         return $this->redirectToRoute('task_success');
    }     return $this->render('default/new.html.twig', array(
        'form' => $form->createView(),
    ));}

1465202253_36066_5344_form-simple.png

本例假设你以"POST"请求提交表单,并且提交到和“表单显示(页面)”相同的URL。后面你将学习如何改变请求方法(request method)和表单提交后的目标URL。

就是这样!只需要三行就可以渲染出完整的form表单:

Annotations:// src/AppBundle/Entity/Task.phpnamespace AppBundle\Entity; use Symfony\Component\Validator\Constraints as Assert; class Task{
    /**
     * @Assert\NotBlank()
     */
    public $task;     /**
     * @Assert\NotBlank()
     * @Assert\Type("\DateTime")
     */
    protected $dueDate;}
YAML:# src/AppBundle/Resources/config/validation.ymlAppBundle\Entity\Task:
    properties:
        task:
            - NotBlank: ~
        dueDate:
            - NotBlank: ~
            - Type: \DateTime
1465202253_36066_5344_form-simple .png Ça y est ! Il suffit de trois lignes pour restituer un formulaire complet : 🎜
    🎜form_start(form)🎜🎜Render la balise de début du formulaire, y compris lors de l'utilisation Corrigez l'attribut enctype lors du téléchargement de fichiers. 🎜🎜form_widget(form)🎜🎜Rend tous les champs, y compris l'élément de champ lui-même, l'étiquette du champ et toute information d'erreur pour la validation du champ. 🎜🎜form_end(form)🎜🎜Lorsque vous générez chaque champ manuellement, il peut restituer la balise de fin du formulaire et tous les champs du formulaire qui n'ont pas encore été rendus. Ceci est utile lors du rendu des champs masqués et pour profiter de la fonction automatique. 🎜🎜Protection CSRF🎜🎜 Très utile pour protéger les mécanismes. 🎜🎜🎜🎜🎜C'est aussi simple que ça, mais pas très flexible (pour l'instant). En règle générale, vous souhaitez afficher chaque champ d'un formulaire individuellement pour contrôler le style du formulaire. Vous maîtriserez cette méthode dans le prochain article 🎜Comment contrôler le rendu des formulaires🎜. 🎜🎜🎜

    Avant de continuer, veuillez noter pourquoi la zone de saisie task rendue a une valeur de propriété provenant de l'objet $task (c'est-à-dire "Écrire un article de blog"). Il s'agit de la première tâche du formulaire : extraire les données d'un objet et les convertir dans un format approprié afin qu'elles puissent être restituées dans un formulaire HTML. task 输入框中有一个来自 $task 对象的属性值(即“Write a blog post”)。这是表单的第一个任务:从一个对象中获取数据并把它转换成一种适当的格式,以便在HTML表单中被渲染。

    表单系统足够智能,它们通过 getTask()setTask() 方法来访问 Task 类中受保护的 task 属性。除非是public属性,否则 必须 有一个 "getter" 和 "setter" 方法被定义,以便表单组件能从这些属性中获取和写入数据。对于布尔型的属性,你可以使用一个 "isser" 和 "hasser" 方法(如  isPublished()hasReminder() )来替代getter方法(getPublished()getReminder())。

    处理表单提交 

    默认时,表单会把POST请求,向“渲染它的同一个控制器”提交回去。

    此处,表单的第二个任务就是把用户提交的数据传回到一个对象的属性之中。要做到这一点,用户提交的数据必须写入表单对象才行。向控制器(Controller)中添加以下功能:

    XML:<!-- src/AppBundle/Resources/config/validation.xml --><?xml version="1.0" encoding="UTF-8"?><constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping        http://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">     <class name="AppBundle\Entity\Task">
            <property name="task">
                <constraint name="NotBlank" />
            </property>
            <property name="dueDate">
                <constraint name="NotBlank" />
                <constraint name="Type">\DateTime</constraint>
            </property>
        </class></constraint-mapping>

    注意 createView() 方法应该在 handleRequest 被调用 之后 再调用。否则,针对 *_SUBMIT

    Le système de formulaires est assez intelligent, ils passent getTask() et setTask( ) pour accéder à la propriété protégée task dans la classe Task. À moins qu'il ne s'agisse d'une propriété publique, doit avoir une méthode "getter" et "setter" définie pour que le composant de formulaire puisse obtenir et écrire des données à partir de ces propriétés. Pour les propriétés booléennes, vous pouvez utiliser une méthode "isser" et "hasser" (telle que isPublished() et hasReminder() ) au lieu d'une méthode getter ( getPublished() et getReminder()).
    🎜🎜

    Traitement de la soumission du formulaire

    🎜Par défaut, le formulaire enverra la requête POST à ​​" Render C'est le même contrôleur" soumis en retour. 🎜🎜Ici, la deuxième tâche du formulaire est de retransférer les données soumises par l'utilisateur vers les propriétés d'un objet. Pour ce faire, les données soumises par l'utilisateur doivent être écrites dans l'objet du formulaire. Ajoutez la fonctionnalité suivante au contrôleur : 🎜
    PHP:// src/AppBundle/Entity/Task.phpuse Symfony\Component\Validator\Mapping\ClassMetadata;use Symfony\Component\Validator\Constraints\NotBlank;use Symfony\Component\Validator\Constraints\Type; class Task{
        // ...     public static function loadValidatorMetadata(ClassMetadata $metadata)
        {
            $metadata->addPropertyConstraint('task', new NotBlank());         $metadata->addPropertyConstraint('dueDate', new NotBlank());
            $metadata->addPropertyConstraint(
                'dueDate',
                new Type('\DateTime')
            );
        }}
    🎜🎜
    🎜Notez que la méthode createView() doit être appelée dans handleRequest Appelez à nouveau après. Dans le cas contraire, les modifications apportées aux événements du formulaire *_SUBMIT ne seront pas appliquées à la couche de vue (comme les messages d'erreur lors de la validation). 🎜🎜

    Le contrôleur suit un modèle commun lors de la gestion des formulaires, qui a trois manières possibles :

    1. Lorsque le navigateur charge initialement une page, le formulaire est créé et affiché. handleRequest() se rend compte que le formulaire n'a pas été soumis et ne fait rien. Si le formulaire n'a pas été soumis, isSubowned() renvoie false;handleRequest() 意识到表单没有被提交进而什么都不做。如果表单未被提交,isSubmitted() 返回false;

    2. 当用户提交表单时,handleRequest() 会识别这个动作并立即将提交的数据写入到 $task 对象的 task and dueDate 属性。然后该对象被验证。如果它是无效的(验证在下一章),isValid() 会返回 false,进而表单被再次渲染,只是这次有验证错误;

    3. 当用户以合法数据提交表单的时,提交的数据会被再次写入到表单,但这一次 isValid() 返回 true。在把用户重定向到其他一些页面之前(如一个“谢谢”或“成功”的页面),你有机会用 $task

    4. Lorsque l'utilisateur soumet le formulaire, handleRequest() reconnaîtra cette action et écrira immédiatement les données soumises dans la tâche de l'objet $task et dueDate. L'objet est ensuite validé. S'il n'est pas valide (la vérification est dans le chapitre suivant), isValid() renverra false et le formulaire sera rendu encore une fois, mais il y a une erreur de validation cette fois ;
      🎜🎜Rediriger l'utilisateur une fois le formulaire soumis avec succès consiste à empêcher l'utilisateur de soumettre des données à plusieurs reprises via le bouton « Actualiser » du navigateur. 🎜🎜🎜

    Validation du formulaire

    Dans la section précédente, vous avez appris comment un formulaire contenant des données valides ou invalides est soumis. Dans Symfony, le processus de vérification est effectué dans l'objet sous-jacent (tel que Task). En d'autres termes, le problème n'est pas de savoir si le "formulaire" est valide, mais si l'objet $task est valide après "les données soumises sont appliquées au formulaire". L'appel de $form->isvalid() est un raccourci pour demander à l'objet $task sous-jacent s'il a obtenu des données valides. Task)。换句话说,问题不在于“表单”是否有效,而是 $task 对象在“提交的数据应用到表单”之后是否合法。调用 $form->isvalid()  是一个快捷方式,询问底层  $task 对象是否获得了合法数据。

    验证(validation)是通过把一组规则(称之为“constraints/约束”)添加到一个类中来完成的。我们给 Task 类添加规则和约束,使task属性不能为空, duDate 字段不空且必须是一个有效的DateTime对象。

    PHP:<!-- app/Resources/views/default/new.html.php --><?php echo $view['form']->form($form, array(
        'attr' => array('novalidate' => 'novalidate'),)) ?>
    Twig:{# app/Resources/views/default/new.html.twig #}
    {{ form(form, {'attr': {'novalidate': 'novalidate'}}) }}
    1
    ->add('dueDate', DateType::class, array('widget' => 'single_text'))

    就是这样!如果你现在重新以非法数据提交表单,你将会看到相应的错误被输出到表单。

    验证是Symfony一个非常强大的功能,它拥有自己的专属章节

    html5验证

    HTML5以来,许多浏览器都原生支持了客户端的验证约束。最常用的验证之激活方式,是在一个必填字段上渲染一个 required 属性(译注:文档中的“渲染”二字,对应英文rendering,可以理解为“输出”。在Symfony中,把从程序底层或控制中向视图层显示内容的过程,称为render)。对于支持HTML5的浏览器来说,如果用户尝试提交一个空字段到表单时,会有一条浏览器原生信息显示出来。

    生成出来的表单充分利用了这个新功能,通过添加一些有意义的HTML属性来触发验证。客户端验证,也可通过把 novalidate 属性添加到 form 标签,或是把 formnovalidate

    La validation s'effectue en ajoutant un ensemble de règles (appelées "contraintes/contraintes") à une classe. Nous ajoutons des règles et des contraintes à la classe Task afin que l'attribut de tâche ne puisse pas être vide et que le champ duDate ne soit pas vide et doive être un objet DateTime valide.

    ->add('dueDate', DateType::class, array(
        'widget' => 'single_text',
        'required' => false))
    ->add('dueDate', DateType::class, array(
        'widget' => 'single_text',
        'label'  => 'Due Date',))
    public function newAction(){
        $task = new Task();     $form = $this->createFormBuilder($task)
            ->add('task')
            ->add('dueDate', null, array('widget' => 'single_text'))
            ->add('save', SubmitType::class)
            ->getForm();}
    1

    C'est tout ! Si vous soumettez à nouveau le formulaire avec des données invalides, vous verrez les erreurs appropriées imprimées sur le formulaire.

    La validation est une fonctionnalité très puissante de Symfony, elle possède son propre chapitre exclusif🎜. 🎜🎜
    🎜validation HTML5🎜🎜Depuis HTML5, de nombreux navigateurs prennent en charge nativement les contraintes de validation côté client. La méthode d'activation de vérification la plus couramment utilisée consiste à restituer un attribut required sur un champ obligatoire (Annotation : Le mot "rendu" dans le document correspond au rendu anglais, qui peut être compris comme "sortie". Dans Dans Symfony, le processus d'affichage du contenu depuis la couche inférieure du programme ou du contrôle vers la couche d'affichage est appelé rendu). Pour les navigateurs prenant en charge HTML5, si l'utilisateur tente de soumettre un champ vide au formulaire, un message natif du navigateur s'affichera. 🎜🎜Le formulaire généré tire pleinement parti de cette nouvelle fonctionnalité en ajoutant des attributs HTML significatifs pour déclencher la validation. La validation côté client peut également être désactivée en ajoutant l'attribut novalidate à la balise form, ou en ajoutant formnovalidate à la balise submit. Ceci est utile si vous souhaitez tester les contraintes de validation côté serveur mais que vous êtes bloqué par le navigateur, par exemple lors de la soumission d'un champ vide. 🎜
    ->add('task', null, array('attr' => array('maxlength' => 4)))
    🎜🎜🎜
    // src/AppBundle/Form/Type/TaskType.phpnamespace AppBundle\Form\Type; use Symfony\Component\Form\AbstractType;use Symfony\Component\Form\FormBuilderInterface;use Symfony\Component\Form\Extension\Core\Type\SubmitType; class TaskType extends AbstractType{
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder
                ->add('task')
                ->add('dueDate', null, array('widget' => 'single_text'))
                ->add('save', SubmitType::class)
            ;
        }}
    🎜🎜

    Types de champs intégrés

    La version standard de Symfony contient un grand nombre de types de champs, couvrant tous les champs de formulaire et types de données conventionnels que vous pouvez rencontrer.

    TextType

    DateTimeType

    RepeatedType# 🎜🎜 #

      champ caché

      Bouton

      FormTypeOptions de type de champ

      Chaque type de champ dispose d'un certain nombre d'options de configuration. Par exemple, le champ

      est actuellement affiché dans 3 zones de sélection. Le champ de date DateType peut être configuré pour s'afficher sous la forme d'une seule zone de texte (l'utilisateur peut saisir une chaîne comme date).

      dueDate

      // src/AppBundle/Controller/DefaultController.phpuse AppBundle\Form\Type\TaskType; public function newAction(){
          $task = ...;
          $form = $this->createForm(TaskType::class, $task);     // ...}
      #🎜🎜 #
      use Symfony\Component\OptionsResolver\OptionsResolver; public function configureOptions(OptionsResolver $resolver){
          $resolver->setDefaults(array(
              'data_class' => 'AppBundle\Entity\Task',
          ));}

      -simple2.png

      Chaque type de champ a un ensemble différent d'options pour transmettre le type. Des détails sur les types de champs peuvent être trouvés dans la documentation de chaque type.

      option requise

      La plus couramment utilisée est l'option obligatoire, qui peut s'appliquer à n'importe quel domaine. Par défaut, il est défini sur true . Cela signifie que les navigateurs prenant en charge HTML5 utiliseront la validation côté client pour déterminer si le champ est vide. Si vous ne souhaitez pas ce comportement, désactivez la validation HTML5 ou définissez l'option obligatoire du champ sur < code >faux. required 选项,它可以应用于任何字段。默认情况下它被设置为 true 。这就意味着支持HTML5的浏览器会使用客户端验证来判断字段是否为空。如果你不想需要这种行为,要么 关闭HTML5验证,要么把字段的 required 选项设置为 false

      use Symfony\Component\Form\FormBuilderInterface; public function buildForm(FormBuilderInterface $builder, array $options){
          $builder
              ->add('task')
              ->add('dueDate', null, array('mapped' => false))
              ->add('save', SubmitType::class)
          ;}

      要注意设置 requiredtrue 意味着服务器端验证会被使用。换句话说,如果用户提交一个空值(blank)到该字段(比如在老旧浏览器中,或是使用web service时),这个空值当被作为有效值予以采纳,除非你使用了Symfony的 NotBlank 或者 NotNull 验证约束。

      也就是说, required 选项是很 "nice",但是服务端验证却应该 始终 使用。

      label选项

      表单字段可以使用label选项来设置表单字段的label,它适用于任何字段:

      1

      字段的label也可以在模版渲染表单时进行设置,见下文。如果你不需要把label关联到你的input(标签),你可以设置选项值为 false

      字段类型猜测 

      现在你已经添加了验证元数据(译注:即annotation)到 Task 类,Symfony对于你的字段已有所了解。如果你允许,Symfony可以“猜到”你的字段类型并帮你设置好。在下面的例子中,Symfony可以根据验证规则猜测到 task 字段是一个标准的 TextType 字段, dueDateDateType 字段。

      $form->get('dueDate')->getData();

      当你省略了 add() 方法的第二个参数(或者你输入 null )时,“猜测”会被激活。如果你输入一个选项数组作为第三个参数(比如上面的 dueDate

      1

      Notez que définir required sur true et

      et non
      signifie que la validation côté serveur sera utilisée. En d'autres termes, si l'utilisateur soumet une valeur vide dans ce champ (comme dans un navigateur plus ancien ou lors de l'utilisation d'un service Web), la valeur vide sera acceptée comme valeur valide, sauf si vous utilisez NotBlank de Symfony. ou NotNull.

      En d'autres termes, l'option obligatoire est "sympa", mais la validation côté serveur doit toujours

      être utilisée.
      #🎜🎜##🎜🎜##🎜🎜##🎜🎜##🎜🎜#label option#🎜🎜##🎜🎜##🎜🎜#Les champs de formulaire peuvent utiliser l'étiquette pour définir l'étiquette du champ du formulaire, qui s'applique à n'importe quel champ : #🎜🎜#
      $form->get('dueDate')->setData(new \DateTime());
      #🎜🎜#L'étiquette du champ peut également être définie lorsque le modèle restitue le formulaire, voir ci-dessous. Si vous n'avez pas besoin d'associer une étiquette à votre entrée, vous pouvez définir la valeur de l'option sur false . #🎜🎜##🎜🎜##🎜🎜##🎜🎜#

      Type de champ devinant

      #🎜🎜#Maintenant que vous avez ajouté des métadonnées de validation (annotation) à la classe Task, Symfony sait déjà quelque chose sur vos champs. Si vous l'autorisez, Symfony peut « deviner » vos types de champs et les configurer pour vous. Dans l'exemple suivant, Symfony peut deviner, en fonction des règles de validation, que le champ task est un champ TextType standard et que dueDate est un . Champ DateType< /code>. #🎜🎜#rrreee#🎜🎜#Lorsque vous omettez le deuxième paramètre de la méthode add() (ou que vous saisissez null ), "Devinez" sera activé. Si vous entrez un tableau d'options comme troisième argument (comme dueDate ci-dessus), ces options seront appliquées au champ deviné. #🎜🎜##🎜🎜##🎜🎜##🎜🎜##🎜🎜#Si votre formulaire utilise un groupe de validation spécifique, deviner le type de champ prendra toujours en compte #🎜🎜#all#🎜 🎜# Les contraintes de validation (y compris les contraintes n'appartenant pas à ce groupe de validation "en cours d'utilisation"). #🎜🎜##🎜🎜##🎜🎜#

      Devinez les options pour les types de champs

      En plus de deviner les types de champs, Symfony peut également essayer de deviner les valeurs correctes pour les options de champ.

      Lorsque ces options sont définies, les champs seront rendus avec des attributs HTML spéciaux pour la validation côté client du HTML5. Cependant, ils ne génèrent pas de règles de validation correspondantes (telles que AssertLength) côté serveur. Bien que vous deviez ajouter ces règles côté serveur manuellement, les options pour ces types de champs peuvent ensuite être devinées en fonction de ces règles. AssertLength )。尽管你需要手动地添加这些服务器端的规则,这些字段类型的选项接下来可以根据这些规则被猜出来。

      • required
      • required 选项可以基于验证规则 (如,该字段是否为 NotBlankNotNull) 或者是Doctrine的metadata元数据 (如,该字段是否为 nullable) 而被猜出来。这非常有用,因为你的客户端验证将自动匹配到你的验证规则。
      • max_length
      • 如果字段是某些列文本型字段,那么 max_length 选项可以基于验证约束 (字段是否应用了 LengthRange) 或者是Doctrine元数据 (通过该字段的长度) 而被猜出来。

      这些字段选项 在你使用Symfony进行类型猜测时(即,忽略参数,或传入null 作为 add()

      Les options
      • obligatoire
      • obligatoire peuvent être basé sur des règles de validation (par exemple, si le champ est NotBlank ou NotNull) ou des métadonnées de doctrine (par exemple, si le champ est deviné pour nullable). Ceci est très utile car votre validation côté client correspondra automatiquement à vos règles de validation.
      • max_length
      • Si le champ est un champ de texte de colonne, alors max_length Les options peuvent être basées sur des contraintes de validation (si le champ a Length ou Plage appliqué) ou des métadonnées de doctrine (via la longueur du champ ) et soyez deviné.

      Ces options de champ sont disponibles uniquement lorsque vous utilisez Symfony pour deviner le type (c'est-à-dire ignorer les arguments ou transmettre < code>null comme deuxième paramètre de la méthode add()) sera deviné.

      Si vous souhaitez modifier une valeur (option) devinée, vous pouvez transmettre cet élément dans le tableau d'options du type de champ pour le remplacer. rrreee
      rrreee
      🎜🎜🎜🎜

      Créer une classe de formulaire

      Comme vous pouvez le constater, les formulaires peuvent être créés et utilisés directement dans le contrôleur. Cependant, une meilleure approche consiste à créer le formulaire dans une classe PHP distincte. Il peut être réutilisé n'importe où dans votre programme. Créez une nouvelle classe contenant la logique nécessaire pour « créer un formulaire de tâche » :

      rrreee

      Cette nouvelle classe contient tous les aspects nécessaires pour créer un formulaire de tâche. Il peut être utilisé pour créer rapidement des formulaires dans un contrôleur.

      rrreee

      Placer la logique du formulaire dans sa propre classe rend le formulaire facilement réutilisable n'importe où dans votre projet. C'est la meilleure façon de créer un formulaire, mais la décision vous appartient.

      Set data_class

      Chaque formulaire doit connaître le nom de la "classe qui contient les données sous-jacentes" (telle que AppBundleEntityTask ). Généralement, cela est deviné en fonction du deuxième argument passé dans la méthode createForm (par exemple $task ). Plus tard, lorsque vous commencez à intégrer des formulaires, cela ne suffit plus. Par conséquent, même si cela n'est pas strictement nécessaire, c'est une bonne idée de spécifier explicitement l'option data_class en ajoutant le code suivant à votre classe de type de formulaire. AppBundleEntityTask )。通常情况下,这是根据传入 createForm 方法的第二个参数来猜测的(例如 $task )。以后,当你开始嵌入表单时,这便不再够用。因此,虽然不是绝对必须,但通过添加下面代码到你的表单类型类中,以显式地指定 data_class 选项是一个好办法。

      rrreee

      当把表单映射成对象时,所有的字段都将被映射。表单中的任何字段如果在映射对象上“不存在”,都会抛出异常。

      当你需要在表单中使用附加字段(如,一个 “你是否同意这些声明?”的复选框)而这个字段将不被映射到底层对象时,你需要设置 mapped 选项为 false

      rrreee

      另外,若表单的任何字段未包含在提交过来的数据中,那么这些字段将被显式设置为 nullrrreee

      Lors du mappage d'un formulaire à un objet, tous les champs seront mappés. Tout champ sous la forme qui "n'existe pas" sur l'objet mappé lèvera une exception.
      Lorsque vous devez utiliser un champ supplémentaire dans un formulaire (par exemple, une case à cocher « Êtes-vous d'accord avec ces déclarations ? ») et que ce champ ne sera pas mappé à l'objet sous-jacent, vous devez définir mapped L'option est false : rrreeeDe plus, si des champs du formulaire ne sont pas inclus dans les données soumises, alors ces champs seront explicitement définis sur null . rrreee
      Dans le contrôleur, nous pouvons accéder aux données du champ (valeur du champ):

      rrreee

      rrreee
      De plus, les données de l'ONU champs mappés, vous peut également le modifier directement :
      🎜🎜🎜rrreee🎜🎜🎜🎜🎜

      Réflexions finales

      Lors de la création d'un formulaire, gardez à l'esprit que l'objectif principal est de convertir les données d'un objet (task) en un formulaire HTML afin que l'utilisateur puisse modifier la valeur (du formulaire) . Le deuxième objectif est d'obtenir les données soumises par l'utilisateur et de réagir sur l'objet.

      Il y a encore beaucoup de choses à maîtriser, et le système Form possède de nombreuses techniques avancées puissantes.