bentuk


Untuk pembangun web, memproses borang HTML ialah salah satu tugas yang paling biasa dan mencabar. Symfony menyepadukan komponen Borang untuk memudahkan pemprosesan borang. Dalam bab ini, anda akan mencipta borang yang kompleks dari awal dan mempelajari ciri penting pustaka borang.

Komponen Borang Symfony ialah perpustakaan kelas bebas yang boleh anda gunakan di luar projek Symfony anda. Rujuk Dokumentasi komponen borang untuk mengetahui lebih lanjut.

Buat borang ringkas

Andaikan anda sedang membina senarai tugasan mudah untuk memaparkan beberapa "tugas". Anda perlu membuat borang untuk membenarkan pengguna anda mengedit dan membuat tugasan. Sebelum itu, mari kita lihat kelas Task, yang boleh membuat dan menyimpan data untuk satu tugasan. 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(),
        ));
    }}

Ini ialah kelas objek PHP asli, kerana ia tidak berinteraksi dengan Symfony atau merujuk perpustakaan lain. Ia ialah kelas objek PHP yang sangat mudah yang secara langsung menyelesaikan masalah data task (task) dalam program your. Sudah tentu, pada penghujung bab ini, anda akan dapat menyerahkan data kepada contoh Task melalui borang HTML, mengesahkan nilainya dan mengekalkannya ke pangkalan data.

Bina borang

Contoh ini menunjukkan cara membina borang anda terus dalam pengawal. Kemudian dalam 🎜Mencipta kelas borang🎜, anda akan menggunakan kelas yang berasingan untuk membina borang Kaedah ini disyorkan kerana borang itu boleh digunakan semula. 🎜🎜

Membuat borang tidak memerlukan banyak kod kerana objek bentuk Symfony dicipta melalui "pembina borang". Tujuan pembangun borang adalah untuk membenarkan anda menulis "arahan" penciptaan borang yang ringkas dan semua tugasan "melebihi beban" semasa membuat borang dilengkapkan oleh pembina.

Dalam contoh ini, anda telah menambah dua medan pada borang, iaitu task dan dueDate. Sepadan dengan atribut task dan dueDate dalam kelas Task. Anda telah menentukan "jenis" FQCN (Nama Kelas Penuh Penuh/nama kelas laluan penuh) untuk mereka masing-masing (seperti TextType, DateType), yang ditentukan oleh taip untuk menjana untuk medan teg bentuk HTML (kumpulan teg). 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
20465 Itu sahaja! Ia hanya mengambil masa tiga baris untuk memaparkan borang yang lengkap: 🎜
    🎜form_start(form)🎜🎜Renderkan teg permulaan borang, termasuk semasa menggunakan Atribut enctype yang betul semasa memuat naik fail. 🎜🎜form_widget(form)🎜🎜Memberikan semua medan, termasuk elemen medan itu sendiri, label medan dan sebarang maklumat ralat untuk pengesahan medan. 🎜🎜form_end(form)🎜🎜Apabila anda menjana setiap medan secara manual, ia boleh menjadikan teg penamat borang dan semua medan dalam borang yang masih belum dipaparkan. Ini berguna apabila memaparkan medan tersembunyi dan memanfaatkan automatik 🎜🎜Perlindungan CSRF🎜🎜 Sangat berguna apabila melindungi mekanisme. 🎜🎜🎜🎜🎜Ia semudah itu, tetapi tidak begitu fleksibel (buat masa ini). Biasanya, anda ingin menjadikan setiap medan dalam bentuk secara individu untuk mengawal gaya borang. Anda akan menguasai kaedah ini dalam artikel seterusnya 🎜Cara Mengawal Rendering Borang🎜. 🎜🎜🎜

    Sebelum meneruskan, sila ambil perhatian mengapa kotak input task yang diberikan mempunyai nilai sifat daripada objek $task (iaitu "Tulis catatan blog"). Ini ialah tugas pertama borang: mendapatkan data daripada objek dan menukarnya kepada format yang sesuai supaya ia boleh dipaparkan dalam bentuk 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

    Sistem borang cukup pintar, mereka lulus getTask() dan setTask( ) untuk mengakses harta task yang dilindungi dalam kelas Task. Melainkan ia adalah harta awam, mesti mempunyai kaedah "pengambil" dan "penetap" yang ditakrifkan supaya komponen borang boleh mendapatkan dan menulis data daripada sifat ini. Untuk sifat boolean, anda boleh menggunakan kaedah "isser" dan "hasser" (seperti isPublished() dan hasReminder() ) dan bukannya kaedah getter ( getPublished() dan getReminder()).
    🎜🎜

    Memproses penyerahan borang

    🎜Secara lalai, borang akan menghantar permintaan POST kepada " Render Ia pengawal yang sama" diserahkan kembali. 🎜🎜Di sini, tugas kedua borang adalah untuk memindahkan data yang diserahkan oleh pengguna kembali ke sifat objek. Untuk melakukan ini, data yang diserahkan oleh pengguna mesti ditulis ke objek borang. Tambahkan fungsi berikut pada Pengawal: 🎜
    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')
            );
        }}
    🎜🎜
    🎜Perhatikan bahawa kaedah createView() harus dipanggil dalam handleRequest Panggil selepas sekali lagi. Jika tidak, pengubahsuaian pada acara borang *_SUBMIT tidak akan digunakan pada lapisan paparan (seperti mesej ralat semasa pengesahan). 🎜🎜

    Pengawal mengikut corak biasa semasa memproses borang Ia mempunyai tiga cara yang mungkin:

    #🎜🎜 #
    1. Apabila. pelayar pada mulanya memuatkan halaman, borang dibuat dan diberikan. handleRequest() menyedari bahawa borang itu belum diserahkan dan tidak melakukan apa-apa. Jika borang tidak diserahkan, isSubmitted() mengembalikan palsu;

    2. handleRequest() 意识到表单没有被提交进而什么都不做。如果表单未被提交,isSubmitted() 返回false;

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

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

      Apabila pengguna menyerahkan borang, handleRequest() akan mengenali tindakan ini dan segera menulis data yang diserahkan kepada tugasan< $task objek. /code> dan atribut dueDate. Objek itu kemudiannya disahkan. Jika ia tidak sah (pengesahan adalah dalam bab seterusnya), isValid() akan mengembalikan false dan borang akan dipaparkan sekali lagi, tetapi Terdapat ralat pengesahan kali ini;
    5. Apabila pengguna menyerahkan borang dengan data undang-undang, data yang diserahkan akan ditulis semula ke borang, tetapi ini masa isValid() mengembalikan true. Sebelum mengubah hala pengguna ke beberapa halaman lain (seperti halaman "Terima kasih" atau "Berjaya"), anda mempunyai peluang untuk menggunakan objek $task untuk melaksanakan beberapa operasi ( seperti meneruskannya ke pangkalan data).

    #🎜🎜#Mengubah hala pengguna selepas borang berjaya diserahkan adalah untuk menghalang pengguna daripada menghantar data berulang kali melalui butang "refresh" pelayar. #🎜🎜##🎜🎜##🎜🎜#

    Jika anda perlu mengawal dengan tepat apabila borang diserahkan, atau data yang dihantar ke borang, anda boleh menggunakan submit(). Untuk maklumat lanjut, sila rujuk Panggilan secara manual Borang::submit().

    Pengesahan Borang

    Dalam bahagian sebelumnya, anda mengetahui cara borang dengan data yang sah atau tidak sah diserahkan. Dalam Symfony, proses pengesahan dilakukan dalam objek asas (seperti Task). Dalam erti kata lain, isunya bukanlah sama ada "borang" itu sah, tetapi sama ada objek $task adalah sah selepas "data yang diserahkan digunakan pada borang". Memanggil $form->isvalid() ialah jalan pintas untuk menanyakan objek $task yang mendasari sama ada ia memperoleh data yang sah. 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

    Pengesahan dicapai dengan menambahkan set peraturan (dipanggil "kekangan/kekangan") pada kelas. Kami menambah peraturan dan kekangan pada kelas Task supaya atribut tugas tidak boleh kosong dan medan duDate tidak kosong dan mestilah objek DateTime yang sah.

    ->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();}

    Itu sahaja! Jika anda kini menyerahkan semula borang dengan data tidak sah, anda akan melihat ralat yang sesuai dicetak pada borang.

    Pengesahan ialah ciri Symfony yang sangat berkuasa, ia mempunyai bab eksklusif🎜nya sendiri. 🎜🎜
    🎜pengesahan HTML5🎜🎜Sejak HTML5, banyak penyemak imbas telah menyokong kekangan pengesahan pihak klien secara asli. Kaedah pengaktifan pengesahan yang paling biasa digunakan adalah untuk memaparkan atribut required pada medan yang diperlukan (Anotasi: Perkataan "rendering" dalam dokumen sepadan dengan rendering bahasa Inggeris, yang boleh difahami sebagai "output". Dalam Dalam Symfony, proses memaparkan kandungan dari lapisan bawah program atau kawalan ke lapisan paparan dipanggil render). Untuk penyemak imbas yang menyokong HTML5, jika pengguna cuba menyerahkan medan kosong ke borang, mesej asli pelayar akan dipaparkan. 🎜🎜Borang yang dijana memanfaatkan sepenuhnya ciri baharu ini dengan menambahkan beberapa atribut HTML yang bermakna untuk mencetuskan pengesahan. Pengesahan pihak pelanggan juga boleh dimatikan dengan menambahkan atribut novalidate pada teg form atau menambahkan formnovalidate pada teg serah. Ini berguna jika anda ingin menguji kekangan pengesahan sisi pelayan tetapi disekat oleh penyemak imbas, contohnya apabila menyerahkan medan kosong. 🎜
    1
    🎜🎜🎜
    ->add('task', null, array('attr' => array('maxlength' => 4)))
    🎜🎜

    Jenis medan terbina dalam

    Versi standard Symfony mengandungi sejumlah besar jenis medan, meliputi semua medan bentuk konvensional dan jenis data yang boleh anda temui.

    TextareaType

    RangeType

    CurrencyType

    Medan jenis lain
    • CheckboxType
    • FileType
    • RadioType

    Field Group

    Medan Tersembunyi

    Butang

    • Jenis Tersembunyi
    • Butang

    ResetType
    • SubmitType

    Borang pangkalan medan Kelas

    dueDateFormType

    Anda juga boleh menentukan jenis medan anda sendiri. Rujuk Cara membuat jenis medan borang tersuai. boleh dikonfigurasikan untuk dijadikan sebagai kotak teks tunggal (pengguna boleh memasukkan rentetan sebagai tarikh).
    Pilihan jenis medan
    Setiap jenis medan mempunyai beberapa pilihan untuk konfigurasi. Sebagai contoh, medan
    dipaparkan kepada 3 kotak terpilih pada masa ini. Dan medan tarikh
    DateType
    🎜🎜🎜🎜🎜
    // 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)
            ;
        }}
    🎜🎜🎜🎜
    // src/AppBundle/Controller/DefaultController.phpuse AppBundle\Form\Type\TaskType; public function newAction(){
        $task = ...;
        $form = $this->createForm(TaskType::class, $task);     // ...}
    🎜🎜🎜🎜🎜

    -simple2.png

    Setiap jenis medan mempunyai set pilihan yang berbeza untuk lulus dalam jenis. Butiran tentang jenis medan boleh didapati dalam dokumentasi untuk setiap jenis.

    pilihan yang diperlukan

    Yang paling biasa digunakan ialah pilihan diperlukan, yang boleh digunakan pada mana-mana medan. Secara lalai ia ditetapkan kepada true . Ini bermakna penyemak imbas yang menyokong HTML5 akan menggunakan pengesahan pihak klien untuk menentukan sama ada medan itu kosong. Jika anda tidak mahu kelakuan ini, sama ada matikan pengesahan HTML5 atau tetapkan pilihan diperlukan medan kepada < kod >salah. required 选项,它可以应用于任何字段。默认情况下它被设置为 true 。这就意味着支持HTML5的浏览器会使用客户端验证来判断字段是否为空。如果你不想需要这种行为,要么 关闭HTML5验证,要么把字段的 required 选项设置为 false

    use Symfony\Component\OptionsResolver\OptionsResolver; public function configureOptions(OptionsResolver $resolver){
        $resolver->setDefaults(array(
            'data_class' => 'AppBundle\Entity\Task',
        ));}

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

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

    label选项

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

    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)
        ;}

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

    字段类型猜测 

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

    1

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

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

    Perhatikan bahawa tetapan diperlukan kepada benar

    tidak
    bermakna pengesahan bahagian pelayan akan digunakan. Dalam erti kata lain, jika pengguna menyerahkan nilai kosong ke medan ini (seperti dalam penyemak imbas lama, atau apabila menggunakan perkhidmatan web), nilai kosong akan diterima sebagai nilai yang sah, melainkan anda menggunakan NotBlank Symfony atau NotNull kekangan pengesahan.

    Maksudnya, pilihan diperlukan adalah "bagus", tetapi pengesahan sebelah pelayan harus sentiasa digunakan.

    🎜🎜🎜🎜pilihan label🎜🎜🎜Medan borang boleh menggunakan pilihan label untuk menetapkan label medan borang, yang digunakan untuk sebarang medan: 🎜
    1
    🎜Label medan boleh juga digunakan untuk membuat borang dalam tetapan templat, lihat di bawah. Jika anda tidak perlu mengaitkan label dengan input anda, anda boleh menetapkan nilai pilihan kepada false . 🎜🎜🎜🎜

    Meneka jenis medan

    🎜Sekarang anda telah menambah metadata pengesahan (Anotasi: Iaitu , anotasi) ke kelas Task, Symfony sudah mengetahui sesuatu tentang medan anda. Jika anda membenarkannya, Symfony boleh "meneka" jenis medan anda dan menyediakannya untuk anda. Dalam contoh berikut, Symfony boleh meneka berdasarkan peraturan pengesahan bahawa medan task ialah medan TextType standard dan dueDate ialah DateType. 🎜
    $form->get('dueDate')->setData(new \DateTime());
    🎜 "Teka" diaktifkan apabila anda meninggalkan parameter kedua kaedah add() (atau anda memasukkan null ). Jika anda memasukkan tatasusunan pilihan sebagai argumen ketiga (seperti dueDate di atas), pilihan ini akan digunakan pada medan tekaan. 🎜🎜🎜🎜🎜Jika borang anda menggunakan kumpulan pengesahan tertentu (kumpulan pengesahan), meneka jenis medan masih akan mempertimbangkan 🎜semua🎜 kekangan pengesahan (termasuk kekangan yang bukan sebahagian daripada kumpulan pengesahan "sedang digunakan" ini). 🎜🎜🎜

    Teka pilihan untuk jenis medan

    Selain meneka jenis medan, Symfony juga boleh cuba meneka nilai yang betul untuk pilihan medan.

    Apabila pilihan ini ditetapkan, medan akan dipaparkan dengan atribut HTML khas untuk pengesahan pihak klien bagi HTML5. Walau bagaimanapun, mereka tidak menjana peraturan pengesahan yang sepadan (seperti AssertLength) pada bahagian pelayan. Walaupun anda perlu menambah peraturan bahagian pelayan ini secara manual, pilihan untuk jenis medan ini kemudiannya boleh diteka berdasarkan peraturan ini. AssertLength )。尽管你需要手动地添加这些服务器端的规则,这些字段类型的选项接下来可以根据这些规则被猜出来。

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

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

    • diperlukan
    • diperlukan pilihan boleh berdasarkan peraturan Pengesahan (contohnya, sama ada medan itu NotBlank atau NotNull) atau metadata Doktrin (contohnya, sama ada medan adalah Diteka untuk nullable). Ini sangat berguna kerana pengesahan pihak klien anda akan secara automatik sepadan dengan peraturan pengesahan anda.
    • max_length
    • Jika medan itu ialah beberapa medan teks lajur, maka max_length Pilihan boleh berdasarkan kekangan pengesahan (sama ada medan mempunyai Panjang atau Julat digunakan) atau metadata Doktrin (melalui panjang medan ) dan diteka.

    Pilihan medan ini tersedia hanya apabila anda menggunakan Symfony untuk meneka jenis (iaitu, abaikan hujah atau hantar masuk < code>null sebagai parameter kedua kaedah add()) akan diteka.

    Jika anda ingin menukar nilai yang telah diteka (pilihan), anda boleh menghantar item ini dalam tatasusunan pilihan jenis medan untuk mengatasinya. rrreee
    rrreee
    🎜🎜🎜🎜

    Buat kelas borang

    Seperti yang anda lihat, borang boleh dibuat dan digunakan terus dalam pengawal. Walau bagaimanapun, pendekatan yang lebih baik ialah mencipta borang dalam kelas PHP yang berasingan. Ia boleh digunakan semula di mana-mana dalam program anda. Cipta kelas baharu yang memegang logik yang diperlukan untuk "membina borang tugas":

    rrreee

    Kelas baharu ini mengandungi semua aspek yang diperlukan untuk mencipta borang tugas. Ia boleh digunakan untuk membuat borang dengan cepat dalam pengawal.

    rrreee

    Meletakkan logik borang dalam kelasnya sendiri menjadikan borang itu mudah digunakan semula di mana-mana sahaja dalam projek anda. Ini adalah cara terbaik untuk membuat borang, tetapi keputusannya terpulang kepada anda.

    Tetapkan kelas_data

    Setiap borang perlu mengetahui nama "kelas yang memegang data asas" (seperti AppBundleEntityTask ). Biasanya, ini diteka berdasarkan hujah kedua yang dihantar ke kaedah createForm (cth. $task ). Kemudian, apabila anda mula membenamkan borang, ini tidak lagi mencukupi. Oleh itu, walaupun ia tidak begitu diperlukan, adalah idea yang baik untuk menentukan secara eksplisit pilihan data_class dengan menambahkan kod berikut pada kelas jenis borang anda. AppBundleEntityTask )。通常情况下,这是根据传入 createForm 方法的第二个参数来猜测的(例如 $task )。以后,当你开始嵌入表单时,这便不再够用。因此,虽然不是绝对必须,但通过添加下面代码到你的表单类型类中,以显式地指定 data_class 选项是一个好办法。

    rrreee

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

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

    rrreee

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

    Apabila memetakan borang ke objek, semua medan akan dipetakan. Mana-mana medan dalam bentuk yang "tidak wujud" pada objek yang dipetakan akan membuang pengecualian.
    Apabila anda perlu menggunakan medan tambahan dalam borang (cth., kotak semak "Adakah anda bersetuju dengan pernyataan ini?") dan medan ini tidak akan dipetakan ke objek asas, anda perlu menetapkan dipetakan Pilihannya adalah palsu: rrreeeSelain itu, jika mana-mana medan borang tidak disertakan dalam data yang diserahkan, maka medan ini akan ditetapkan secara eksplisit kepada null . rrreee
    Dalam pengawal kita boleh mengakses data medan (nilai medan):

    rrreee

    dalam penambahan data.rrreee
    bidang, awak boleh juga ubah suai terus:
    🎜🎜rrreee🎜🎜🎜🎜🎜

    Fikiran Akhir

    Apabila membina borang, perlu diingat bahawa matlamat utama adalah untuk menukar data objek (task) ke dalam bentuk HTML supaya pengguna boleh mengubah suai nilai (bentuk) . Matlamat kedua adalah untuk mendapatkan data yang diserahkan oleh pengguna dan bertindak semula pada objek.

    Masih banyak yang perlu dikuasai, dan sistem Borang mempunyai banyak perkasa teknik lanjutan.