Rumah > hujung hadapan web > tutorial css > Membina Borang dalam PHP Menggunakan Domdocument

Membina Borang dalam PHP Menggunakan Domdocument

Christopher Nolan
Lepaskan: 2025-03-20 11:01:12
asal
953 orang telah melayarinya

Membina Borang dalam PHP Menggunakan Domdocument

Templat untuk menjadikan rangkaian berfungsi. Kandungan sintesis data dan struktur. Bagi pemaju, ini adalah kuasa besar kami yang paling keren - dapatkan beberapa data dan kemudian ia berfungsi untuk kami, menjadikannya dalam apa jua bentuk yang kami perlukan. Pelbagai objek boleh diubah menjadi meja, senarai kad, carta, atau apa sahaja yang kami fikir paling berguna kepada pengguna. Sama ada data adalah catatan blog dalam fail markdown kami sendiri atau kadar pertukaran global terkini, markup dan pengalaman pengguna muktamad terpulang kepada pemaju depan kami.

PHP adalah bahasa yang kuat untuk templat yang menyediakan banyak cara untuk menggabungkan data dengan tag. Mari kita lihat contoh menggunakan data untuk membina borang HTML.

Ingin memulakan sekarang? Lompat ke bahagian pelaksanaan.

Dalam PHP, kita dapat menyamakan pembolehubah ke dalam literal rentetan menggunakan petikan berganda, jadi jika kita mempunyai pembolehubah $name = 'world' kita boleh menulis echo "Hello, {$name}" yang mencetak "hello, dunia" yang diharapkan. Untuk templat yang lebih kompleks, kita boleh menyatukan rentetan, contohnya: echo "Hello, " . $name . "." .

Untuk pengaturcara lama, terdapat juga printf("Hello, %s", $name) . Untuk rentetan berbilang baris, Heredoc boleh digunakan (serupa dengan Hello, = $name ?> ). Semua pilihan ini hebat, tetapi perkara -perkara boleh menjadi kemas apabila banyak logik sebaris diperlukan. Jika kita perlu membina rentetan HTML komposit, seperti bentuk atau navigasi, maka kerumitan mungkin tidak terhingga, kerana unsur -unsur HTML dapat bersarang antara satu sama lain.

Apa yang kita cuba elakkan

Sebelum kita terus melakukan apa yang kita mahu lakukan, ia bernilai satu minit untuk memikirkan apa yang kita tidak mahu lakukan. Pertimbangkan petikan dari baris 170-270 kod teras WordPress class-walker-nav-menu.php :

  php // class-walker-nav-menu.php
// ...
$ output. = $ indent. '
Salin selepas log masuk
  • '; // ... $ item_output = $ args-> sebelum; $ item_output. = ' '; $ item_output. = $ args-> link_before. $ item_output. = ' '; $ item_output. = $ args-> selepas; // ... $ output. = apply_filters ('walker_nav_menu_start_el', $ item_output, $ item, $ kedalaman, $ args); // ... $ output. = "{$ n}";

    Untuk membina navigasi, dalam fungsi ini, kami menggunakan $output yang berubah -ubah, yang merupakan rentetan yang sangat panjang, dan kami terus menambah kandungan kepadanya. Kod jenis ini mempunyai susunan operasi yang sangat spesifik dan terhad. Sekiranya kita mahu<a></a> Tambah harta yang kita perlu mengakses $attributes sebelum ia berjalan. Sekiranya kita mahu<a></a> Sarang pilihan<span></span> Atau a<img alt="Membina Borang dalam PHP Menggunakan Domdocument" > , kita perlu menulis blok kod baru, menggantikan bahagian tengah baris 7 dengan kira-kira 4-10 baris kod baru, bergantung kepada apa yang kita mahu tambah. Sekarang bayangkan anda perlu menambah pilihan<span></span> , kemudian menambah pilihan<img alt="Membina Borang dalam PHP Menggunakan Domdocument" > , atau dalam<span></span> Tambah secara dalaman atau lambat. Ini sendiri adalah tiga jika kenyataan, menjadikan kod lebih sukar untuk dibaca. Apabila menggabungkan rentetan seperti ini, mudah untuk berakhir dengan pasta rentetan, yang menyeronokkan untuk dikatakan tetapi menyakitkan untuk dikekalkan.

    Inti masalahnya ialah apabila kita cuba menyimpulkan unsur -unsur HTML, kita tidak memikirkan rentetan . Penyemak imbas hanya menggunakan rentetan, dan php output rentetan. Tetapi model mental kita lebih seperti unsur-unsur dom disusun dalam struktur seperti pokok, dan setiap nod mempunyai banyak sifat, ciri-ciri dan nod kanak-kanak.

    Bukankah lebih baik jika ada cara berstruktur dan sangat ekspresif untuk membina pokok?

    Masukkan ……

    Kelas Domdocument

    Php 5 menambah modul DOM ke barisan yang tidak ditaip. Titik kemasukan utamanya ialah kelas domdokumen, yang bertujuan untuk menjadi serupa dengan dom JavaScript API Web. Jika anda pernah menggunakan document.createElement , atau untuk beberapa umur kami, gunakan JQuery's $(' Hi there!

    ') Sintaks, yang mungkin terasa sangat akrab. Kami mula -mula memulakan domdokumen baru:
     $ dom = domDocument baru ();
    Salin selepas log masuk

    Sekarang kita boleh menambah domelemen kepadanya:

     $ p = $ dom-> createeLement ('p');
    Salin selepas log masuk

    Rentetan 'P' mewakili jenis elemen yang kita mahu, jadi rentetan yang sah lain boleh 'div', 'img', dll.

    Sebaik sahaja kita mempunyai elemen, kita boleh menetapkan sifatnya:

     $ p-> setAttribute ('class', 'headline');
    Salin selepas log masuk

    Kami boleh menambah nod kanak -kanak ke dalamnya:

     $ span = $ dom-> createelement ('span', 'ini adalah tajuk utama');
    $ p-> appendchild ($ span);
    Salin selepas log masuk

    Akhirnya, dapatkan rentetan HTML yang lengkap sekaligus:

     $ dom-> appendChild ($ p);
    $ htmlstring = $ dom-> saveHtml ();
    echo $ htmlstring;
    Salin selepas log masuk

    Perhatikan bahawa gaya pengekodan ini membolehkan kod kami dianjurkan mengikut model mental kami -dokumen ini mengandungi unsur -unsur; Bahagian "HTML hanya rentetan" muncul pada akhirnya, apabila struktur kami berada di tempat. "Dokumen" sedikit berbeza dari DOM sebenar di sini, kerana ia tidak perlu mewakili keseluruhan dokumen, tetapi hanya blok HTML. Sebenarnya, jika anda perlu membuat dua elemen yang sama, anda boleh menyimpan rentetan HTML menggunakan saveHTML() , mengubah suai "dokumen" DOM, dan kemudian simpan rentetan HTML baru dengan menghubungi saveHTML() sekali lagi.

    Dapatkan data dan tetapkan struktur

    Katakan kita perlu membina borang pada pelayan menggunakan data dari pembekal CRM dan tag kita sendiri. Tanggapan API dari CRM kelihatan seperti ini:

     {
      "Hantar_button_label": "Hantar sekarang!",
      "Bidang": [
        {
          "id": "nama pertama",
          "jenis": "teks",
          "label": "nama pertama",
          "Diperlukan": Benar,
          "validation_message": "Nama pertama diperlukan.",
          "max_length": 30
        },
        {
          "id": "kategori",
          "jenis": "Multiple_Choice",
          "label": "Pilih semua kategori yang dikenakan",
          "Diperlukan": palsu,
          "field_metadata": {
            "Multi_Select": Benar,
            "Nilai": [
              {"nilai": "perjalanan", "label": "perjalanan"},
              {"nilai": "pemasaran", "label": "pemasaran"}
            ]
          }
        }
      ]
    }
    Salin selepas log masuk

    Contoh ini tidak menggunakan struktur data yang tepat bagi mana -mana CRM tertentu, tetapi ia agak mewakili.

    Dan katakan kami mahu tag kami kelihatan seperti ini:

    <label>
      <input type="text" placeholder=" " id="first-name" required maxlength="30">
      Nama pertama
      <em>Nama pertama diperlukan.</em>
    </label>
    <label>
      </label>
        <div>
          <input type="checkbox" value="travel" id="category-travel" name="category">
          <label for="category-travel">Perjalanan</label>
        </div>
        <div>
          <input type="checkbox" value="marketing" id="category-marketing" name="category">
          <label for="category-marketing">Pemasaran</label>
        </div>
      
      Pilih semua kategori yang dikenakan
    
    Salin selepas log masuk

    Apakah pemegang tempat ""? Ini adalah helah kecil yang membolehkan kita mengesan sama ada medan kosong di CSS tanpa menggunakan JavaScript. Selagi input kosong, ia sepadan dengan input:placeholder-shown , tetapi pengguna tidak akan melihat apa-apa teks pemegang tempat yang kelihatan. Inilah yang boleh kita lakukan apabila kita mengawal markup!

    Sekarang kita tahu apa yang ingin kita capai, inilah rancangan permainan:

    1. Dapatkan definisi medan dan kandungan lain dari API
    2. Inisialisasi domdocument
    3. Melangkah ke ladang dan membina setiap bidang yang diperlukan
    4. Dapatkan output HTML

    Oleh itu, mari kita bina proses kami dan selesaikan beberapa masalah teknikal:

      Php Function RenderForm ($ endpoint) {
      // Dapatkan data dari API dan tukarnya menjadi objek php $ formResult = file_get_contents ($ endpoint);
      $ formContent = json_decode ($ formResult);
      $ formfields = $ formContent-> fields;
    
      // mula membina dom
      $ dom = domDocument baru ();
      $ form = $ dom-> createeLement ('form');
    
      // melangkah ke atas bidang dan membina setiap medan foreach ($ formfields sebagai $ medan) {
        // Todo: Lakukan beberapa operasi pada data medan}
    
      // Dapatkan output html $ dom-> appendChild ($ form);
      $ htmlstring = $ dom-> saveHtml ();
      echo $ htmlstring;
    }
    Salin selepas log masuk

    Setakat ini, kami telah mengambil dan menghuraikan data, memulakan domdokumen kami dan bergema outputnya. Apa yang kita mahu lakukan dengan setiap bidang? Pertama, mari kita membina elemen kontena, dalam contoh kita, sepatutnya<label></label> , dan tag yang biasa untuk semua jenis medan:

      php // ...
    // melangkah ke atas bidang dan membina setiap medan foreach ($ formfields sebagai $ medan) {
      // membina <label>bekas```
      $ elemen = $ dom-> createeLement ('label');
      $ elemen-> setAttribute ('kelas', 'medan');
    
      // Tetapkan semula nilai input $ label = null;
    
      // Sekiranya tag ditetapkan, tambah ` <span>`
      jika ($ field-> label) {
        $ label = $ dom-> createeLement ('span', $ field-> label);
        $ label-> setAttribute ('kelas', 'label');
      }
    
      // tambah tag ke `` <label>`
      jika ($ label) $ elemen-> appendChild ($ label);
    }</label></span></label><p> Oleh kerana kita berada dalam gelung dan PHP tidak skop pembolehubah dalam gelung, kita menetapkan semula elemen <code>$label</code> pada setiap lelaran. Kemudian, jika medan mempunyai label, kami membina elemen. Akhirnya, kami menambahkannya ke elemen kontena.</p><p> Sila ambil perhatian bahawa kami menggunakan kaedah <code>setAttribute</code> untuk menetapkan kelas. Tidak seperti API Web, malangnya, tidak ada rawatan khas untuk senarai kelas. Mereka hanya sifat lain. Jika kita mempunyai beberapa logik kelas yang sangat kompleks, kerana ia hanya PHP ™, kita boleh membuat array dan sebarisnya: <code>$label->setAttribute('class', implode($labelClassList))</code> .</p><h3> Input tunggal</h3><p> Oleh kerana kita tahu bahawa API hanya akan mengembalikan jenis medan tertentu, kita boleh menukar jenis dan menulis kod khusus untuk setiap jenis:</p><pre class="brush:php;toolbar:false">  php // ...
    // melangkah ke atas bidang dan membina setiap medan foreach ($ formfields sebagai $ medan) {
      // membina <label>bekas```
      $ elemen = $ dom-> createeLement ('label');
      $ elemen-> setAttribute ('kelas', 'medan');
    
      // Tetapkan semula nilai input $ input = null;
      $ label = null;
    
      // Sekiranya tag ditetapkan, tambah ` <span>`
      // ...
    
      // membina suis elemen input ($ field-> type) {
        kes 'teks':
        kes 'e -mel':
        kes 'telefon':
          $ input = $ dom-> createeLement ('input');
          $ input-> setAttribute ('placeholder', '');
          jika ($ field-> type === 'email') $ input-> setAttribute ('type', 'e-mel');
          jika ($ field-> type === 'telefon') $ input-> setAttribute ('type', 'tel');
          rehat;
      }
    }</span></label><p> Sekarang mari kita berurusan dengan kawasan teks, kotak semak tunggal, dan medan tersembunyi:</p><pre class="brush:php;toolbar:false">  php // ...
    // melangkah ke atas bidang dan membina setiap medan foreach ($ formfields sebagai $ medan) {
      // membina <label>bekas```
      $ elemen = $ dom-> createeLement ('label');
      $ elemen-> setAttribute ('kelas', 'medan');
    
      // Tetapkan semula nilai input $ input = null;
      $ label = null;
    
      // Sekiranya tag ditetapkan, tambah ` <span>`
      // ...
    
      // membina suis elemen input ($ field-> type) {
        // ...
        kes 'text_area':
          $ input = $ dom-> createeLement ('textarea');
          $ input-> setAttribute ('placeholder', '');
          jika ($ baris = $ field-> field_metadata-> baris) $ input-> setAttribute ('baris', $ baris);
          rehat;
    
        kes 'kotak semak':
          $ elemen-> setAttribute ('class', 'field single-checkbox');
          $ input = $ dom-> createeLement ('input');
          $ input-> setAttribute ('Type', 'Checkbox');
          jika ($ field-> field_metadata-> awalnya_checked === true) $ input-> setAttribute ('diperiksa', 'diperiksa');
          rehat;
    
        kes 'tersembunyi':
          $ input = $ dom-> createeLement ('input');
          $ input-> setAttribute ('type', 'hidden');
          $ input-> setAttribute ('nilai', $ field-> field_metadata-> value);
          $ elemen-> setAttribute ('tersembunyi', 'tersembunyi');
          $ elemen-> setAttribute ('gaya', 'paparan: tiada;');
          $ label-> textContent = '';
          rehat;
      }
    }</span></label><p> Perhatikan beberapa tindakan baru yang telah kami lakukan dengan kotak semak dan situasi tersembunyi? Kami bukan sahaja mencipta<code><input></code> elemen <em>;</em><code><label></label></code> elemen! Untuk medan kotak semak tunggal, kami ingin mengubah suai kelas kontena supaya kami dapat menyelaraskan kotak semak dan label secara mendatar;<code><label></label></code> Bekas juga harus tersembunyi sepenuhnya.</p><p> Sekarang, jika kita hanya menyambung rentetan, maka ia tidak boleh diubah pada ketika ini. Kami perlu menambah sekumpulan jika pernyataan mengenai jenis elemen dan metadata mereka di bahagian atas blok. Atau, mungkin lebih buruk, kita mula beralih lebih awal dan salinan-paste banyak kod awam di antara setiap cawangan.</p><p> Dan itulah manfaat sebenar menggunakan pembina seperti domdocument - semuanya masih boleh diedit dan semuanya masih berstruktur sehingga kita mengklik <code>saveHTML()</code> .</p><h3> Elemen gelung bersarang</h3><p> Mari tambah<code><select></select></code> Logik elemen:</p><pre class="brush:php;toolbar:false">  php // ...
    // melangkah ke atas bidang dan membina setiap medan foreach ($ formfields sebagai $ medan) {
      // membina <label>bekas```
      $ elemen = $ dom-> createeLement ('label');
      $ elemen-> setAttribute ('kelas', 'medan');
    
      // Tetapkan semula nilai input $ input = null;
      $ label = null;
    
      // Sekiranya tag ditetapkan, tambah ` <span>`
      // ...
    
      // membina suis elemen input ($ field-> type) {
        // ...
        kes 'pilih':
          $ elemen-> setAttribute ('kelas', 'medan pilih');
          $ input = $ dom-> createeLement ('pilih');
          $ input-> setAttribute ('diperlukan', 'diperlukan');
          jika ($ field-> field_metadata-> multi_select === benar)
            $ input-> setAttribute ('Multiple', 'Multiple');
    
          $ options = [];
    
          // Jejak sama ada terdapat pilihan yang dipilih $ options dipilih = palsu;
    
          foreach ($ field-> field_metadata-> nilai sebagai nilai $) {
            $ option = $ dom-> createeLement ('opsyen', htmlspecialchars ($ value-> label));
    
            // Jika tidak ada nilai, langkau jika (! $ Value-> nilai) teruskan;
    
            // Tetapkan pilihan yang dipilih jika ($ value-> dipilih === benar) {
              $ option-> setAttribute ('dipilih', 'dipilih');
              $ optionelected = true;
            }
            $ option-> setAttribute ('value', $ value-> value);
            $ option [] = $ option;
          }
    
          // Jika tidak ada pilihan yang dipilih, bina pilihan tempat letak kosong jika ($ optionelected === false) {
            $ empyOption = $ dom-> createeLement ('option');
    
            // Tetapkan pilihan untuk menyembunyikan, melumpuhkan dan pilih Foreach (['tersembunyi', 'dilumpuhkan', 'dipilih'] sebagai atribut $)
              $ empyOption-> setAttribute ($ atribut, $ atribut);
            $ input-> appendChild ($ empyOption);
          }
    
          // Tambah pilihan dalam array ke ` <select>`
          foreach ($ pilihan sebagai pilihan $) {
            $ input-> appendChild ($ pilihan);
          }
          rehat;
      }
    }</select></span></label><p> Ok, ada banyak perkara yang perlu dilakukan di sini, tetapi logik yang mendasari adalah sama. Tetapan luaran<code><label></label></code> Selepas itu, kami membuat a<code><option></option></code> array, tambahnya.</p><p> Kami juga melakukan beberapa di sini<code><select></select></code> Trik Khas: Jika tidak ada pilihan pra-pilih, kami akan menambah pilihan pemegang tempat kosong yang telah dipilih, tetapi pengguna tidak boleh memilihnya. Matlamatnya adalah menggunakan CSS untuk memindahkan kami<code><label></label></code> Sebagai "pemegang tempat", tetapi teknologi ini boleh digunakan dalam pelbagai reka bentuk. Dengan menambahkannya ke <code>$input</code> sebelum melaksanakan pilihan lain, kami pastikan ia adalah pilihan pertama dalam tag.</p><p> Mari berurusan dengannya sekarang<code><fieldset></fieldset></code> Butang radio dan kotak semak di:</p><pre class="brush:php;toolbar:false">  php // ...
    // melangkah ke atas bidang dan membina setiap medan foreach ($ formfields sebagai $ medan) {
      // membina <label>bekas```
      $ elemen = $ dom-> createeLement ('label');
      $ elemen-> setAttribute ('kelas', 'medan');
    
      // Tetapkan semula nilai input $ input = null;
      $ label = null;
    
      // Sekiranya tag ditetapkan, tambah ` <span>`
      // ...
    
      // membina suis elemen input ($ field-> type) {
        // ...
        Kes 'Multiple_Choice':
          $ choiceType = $ field-> field_metadata-> Multi_Select === True?
          $ elemen-> setAttribute ('class', "field {$ choiceType} -group");
          $ input = $ dom-> createeLement ('fieldSet');
    
          // Bina pilihan `` untuk setiap pilihan dalam medan</span></label>
          foreach ($ field-> field_metadata-> nilai sebagai $ choicevalue) {
            $ choiceField = $ dom-> createeLement ('div');
            $ choiceField-> setAttribute ('class', 'choice');
    
            // Gunakan ID medan untuk memilih ID untuk menetapkan ID unik
            $ choiceId = "{$ field-> id}-{$ choicevalue-> value}";
    
            // membina`<input> `Elemen $ pilihan = $ dom-> createeLement ('input');
            $ pilihan-> setAttribute ('type', $ choiceType);
            $ pilihan-> setAttribute ('nilai', $ choiceValue-> value);
            $ pilihan-> setAttribute ('id', $ choiceId);
            $ pilihan-> setAttribute ('nama', $ field-> id);
            $ choiceField-> appendChild ($ choice);
    
            // membina ` <label>` `elemen $ choicelabel = $ dom-> createeLement ('label', $ choicevalue-> label);
            $ choicelabel-> setAttribute ('for', $ choiceId);
            $ choiceField-> appendChild ($ Choicelabel);
    
            $ input-> appendChild ($ choiceField);
          }
          rehat;
      }
    }</label><p> Oleh itu, pertama kita menentukan sama ada set medan harus menjadi kotak pilihan atau butang radio. Kemudian kami menetapkan kelas kontena dengan sewajarnya dan membina<code><fieldset></fieldset></code> . Selepas itu, kami melangkah ke atas pilihan yang tersedia dan membina satu untuk setiap pilihan<code><div> , yang mengandungi satu<code><input></code> Dan satu<code><label></label></code> . Perhatikan bahawa kami menetapkan kelas kontena pada baris 21 menggunakan interpolasi rentetan PHP biasa dan membuat ID unik dalam baris 30 untuk setiap pilihan.<h3> Fragmen</h3>
    <p> Jenis terakhir yang perlu kita tambah adalah sedikit lebih kompleks daripada yang kelihatannya. Banyak bentuk mengandungi medan perihalan yang bukan input, tetapi hanya beberapa HTML yang kita perlukan untuk mencetak di antara medan lain.</p>
    <p> Kita perlu menggunakan kaedah domdocument lain <code>createDocumentFragment()</code> . Ini membolehkan kita menambah HTML sewenang -wenang tanpa menggunakan struktur DOM:</p>
    <pre class="brush:php;toolbar:false">  php // ...
    // melangkah ke atas bidang dan membina setiap medan foreach ($ formfields sebagai $ medan) {
      // membina <label>bekas```
      $ elemen = $ dom-> createeLement ('label');
      $ elemen-> setAttribute ('kelas', 'medan');
    
      // Tetapkan semula nilai input $ input = null;
      $ label = null;
    
      // Sekiranya tag ditetapkan, tambah ` <span>`
      // ...
    
      // membina suis elemen input ($ field-> type) {
        // ...
        Kes 'Arahan':
          $ elemen-> setAttribute ('kelas', 'teks medan');
          $ fragment = $ dom-> creationCumentFragment ();
          $ fragment-> appendxml ($ field-> text);
          $ input = $ dom-> createeLement ('p');
          $ input-> appendchild ($ fragmen);
          rehat;
      }
    }</span></label><p> Pada ketika ini anda mungkin tertanya -tanya bagaimana kami mendapat objek bernama <code>$input</code> yang sebenarnya mewakili statik<code><p> elemen. Matlamatnya adalah menggunakan nama pembolehubah biasa untuk setiap lelaran gelung medan, jadi pada akhirnya kita boleh menambahnya dengan <code>$element->appendChild($input)</code> tanpa mengira jenis medan sebenar. Jadi, ya, menamakan perkara -perkara yang sukar.</p>
    <h3> Sahkan</h3>
    <p> API yang kami gunakan menyediakan mesej pengesahan berasingan untuk setiap medan yang diperlukan. Jika ralat komit berlaku, kita boleh memaparkan ralat sejajar dengan medan dan bukannya menunjukkan mesej "oops, salah" anda di bahagian bawah.</p>
    <p> Mari tambahkan teks pengesahan ke setiap elemen:</p>
    <pre class="brush:php;toolbar:false">  php // ...
    // melangkah ke atas bidang dan membina setiap medan foreach ($ formfields sebagai $ medan) {
      // membina <label>bekas```
      $ elemen = $ dom-> createeLement ('label');
      $ elemen-> setAttribute ('kelas', 'medan');
    
      // Tetapkan semula nilai input $ input = null;
      $ label = null;
      $ pengesahan = null;
    
      // Sekiranya tag ditetapkan, tambah ` <span>`
      // ...
    
      // Sekiranya mesej pengesahan ditetapkan, tambah ` <em>`
      jika (isset ($ field-> validation_message)) {
        $ pengesahan = $ dom-> createeLement ('em');
        $ fragment = $ dom-> creationCumentFragment ();
        $ fragment-> appendxml ($ field-> validation_message);
        $ pengesahan-> appendChild ($ fragmen);
        $ validation-> setAttribute ('class', 'validation-message');
        $ pengesahan-> setAttribute ('tersembunyi', 'tersembunyi');
    
      // membina suis elemen input ($ field-> type) {
        // ...
      }
    }</em></span></label><p> Itu sahaja! Tidak perlu berurusan dengan logik jenis medan - hanya membina satu elemen untuk setiap bidang.</p><h3> Mengintegrasikan semua kandungan</h3><p> Jadi apa yang berlaku selepas kita membina semua elemen lapangan? Kami perlu menambah <code>$input</code> , <code>$label</code> dan <code>$validation</code> ke Dom Tree yang kami bina. Kami juga boleh mengambil kesempatan daripada peluang ini untuk menambah sifat awam, seperti <code>required</code> . Kami kemudian akan menambah butang Hantar, yang berasingan dari medan dalam API ini.</p><pre class="brush:php;toolbar:false">  Php Function RenderForm ($ endpoint) {
      // Dapatkan data dari API dan menukarnya menjadi objek php // ...
    
      // mula membina dom
      $ dom = domDocument baru ();
      $ form = $ dom-> createeLement ('form');
    
      // melangkah ke atas bidang dan membina setiap medan foreach ($ formfields sebagai $ medan) {
        // membina <label>bekas```
        $ elemen = $ dom-> createeLement ('label');
        $ elemen-> setAttribute ('kelas', 'medan');
    
        // Tetapkan semula nilai input $ input = null;
        $ label = null;
        $ pengesahan = null;
    
        // Sekiranya tag ditetapkan, tambah ` <span>`
        // ...
    
        // Sekiranya mesej pengesahan ditetapkan, tambah ` <em>`
        // ...
    
        // membina suis elemen input ($ field-> type) {
          // ...
        }
    
        // Tambah elemen input jika ($ input) {
          $ input-> setAttribute ('id', $ field-> id);
          jika ($ medan-> diperlukan)
            $ input-> setAttribute ('diperlukan', 'diperlukan');
          jika (isset ($ field-> max_length))
            $ input-> setAttribute ('maxLength', $ field-> max_length);
          $ elemen-> appendChild ($ input);
    
          jika ($ label)
            $ elemen-> appendChild ($ label);
    
          jika (pengesahan $)
            $ elemen-> appendChild ($ pengesahan);
    
          $ form-> appendchild ($ elemen);
        }
      }
    
      // Bina butang hantar $ hantarButtonLabel = $ formContent-> clopmer_button_label;
      $ hantarButtonField = $ dom-> createeLement ('div');
      $ hantarButtonField-> setAttribute ('Class', 'Field Drop');
      $ hantarButton = $ dom-> createeLement ('butang', $ hantarButtonLabel);
      $ hantarButtonField-> appendChild ($ SubmitButton);
      $ form-> appendChild ($ clopmitButtonField);
    
      // Dapatkan output html $ dom-> appendChild ($ form);
      $ htmlstring = $ dom-> saveHtml ();
      echo $ htmlstring;
    }</em></span></label><p> Mengapa kita menyemak sama ada <code>$input</code> adalah benar? Oleh kerana kami menetapkannya semula ke batal di bahagian atas gelung dan membinanya hanya jika jenis sepadan dengan kes suis yang kami harapkan, ini memastikan bahawa kami tidak secara tidak sengaja memasukkan unsur -unsur yang tidak dijangka yang tidak dapat dikendalikan oleh kod kami dengan betul.</p><p> Lihat, borang HTML tersuai!</p><h3> Kandungan tambahan: baris dan lajur</h3><p> Seperti yang anda ketahui, banyak pembina bentuk membenarkan penulis menetapkan baris dan lajur untuk medan. Sebagai contoh, baris mungkin mengandungi medan nama pertama dan terakhir, masing -masing dalam lajur lebar 50% berasingan. Jadi, anda mungkin bertanya, bagaimana kita boleh mencapai ini? Sudah tentu, mari kita menggambarkan keramahan keramahan domdokumen dengan memberikan contoh!</p><p> Tanggapan API kami mengandungi data grid seperti yang ditunjukkan di bawah:</p><pre class="brush:php;toolbar:false"> {
      "Hantar_button_label": "Hantar sekarang!",
      "Bidang": [
        {
          "id": "nama pertama",
          "jenis": "teks",
          "label": "nama pertama",
          "Diperlukan": Benar,
          "validation_message": "Nama pertama diperlukan.",
          "max_length": 30,
          "baris": 1,
          "lajur": 1
        },
        {
          "id": "kategori",
          "jenis": "Multiple_Choice",
          "label": "Pilih semua kategori yang dikenakan",
          "Diperlukan": palsu,
          "field_metadata": {
            "Multi_Select": Benar,
            "Nilai": [
              {"nilai": "perjalanan", "label": "perjalanan"},
              {"nilai": "pemasaran", "label": "pemasaran"}
            ]
          },
          "baris": 2,
          "lajur": 1
        }
      ]
    }
    Salin selepas log masuk

    Kami mengandaikan bahawa menambah harta data-column sudah cukup untuk menetapkan lebar, tetapi setiap baris memerlukan elemennya sendiri (iaitu tanpa grid CSS).

    Sebelum kita menggali lebih mendalam, mari kita pertimbangkan apa yang kita perlukan untuk menambah baris. Logik asas adalah seperti berikut:

    1. Jejaki baris terkini yang dihadapi.
    2. Jika garis semasa lebih besar, iaitu kami melompat ke baris seterusnya, membuat elemen baris baru dan mula menambah kandungan kepadanya, dan bukannya menambahkannya ke baris sebelumnya.

    Sekarang, apa yang perlu kita lakukan jika kita menggabungkan rentetan? Mungkin menambah rentetan yang serupa dengan ' <div>'</div> setiap kali barisan baru dicapai. Ini "rentetan html terbalik" sentiasa sangat mengelirukan kepada saya, jadi saya hanya dapat membayangkan apa yang dirasakan sebagai IDE saya. Paling penting, kerana penyemak imbas secara automatik menutup tag terbuka, kesilapan mudah boleh membawa kepada bersarang yang tidak terhitung jumlahnya<div> . Ia seperti menyeronokkan, tetapi sebaliknya. Jadi, apakah pendekatan berstruktur untuk menangani masalah ini? Terima kasih atas soalan anda. Pertama, mari tambahkan jejak baris sebelum gelung dan bina elemen kontena baris tambahan. Kami kemudian akan memastikan untuk menambah setiap <code>$element ke $rowElement dan bukannya secara langsung menambahkan ke $form .

      Php Function RenderForm ($ endpoint) {
      // Dapatkan data dari API dan menukarnya menjadi objek php // ...
    
      // mula membina dom
      $ dom = domDocument baru ();
      $ form = $ dom-> createeLement ('form');
    
      // Inisialisasi penjejakan baris $ row = 0;
      $ rowElement = $ dom-> createeLement ('div');
      $ rowElement-> setAttribute ('class', 'field-row');
    
      // melangkah ke atas bidang dan membina setiap medan foreach ($ formfields sebagai $ medan) {
        // membina <label>bekas```
        $ elemen = $ dom-> createeLement ('label');
        $ elemen-> setAttribute ('kelas', 'medan');
        $ elemen-> setAttribute ('data-row', $ field-> row);
        $ elemen-> setAttribute ('data-column', $ field-> column);
    
        // Tambah elemen input ke baris jika ($ input) {
          // ...
          $ rowElement-> appendChild ($ element);
          $ form-> appendchild ($ rowElement);
        }
      }
      // ...
    }</label><p> Setakat ini kami baru sahaja menambah satu lagi di sekitar padang<code><div> . Mari buat elemen baris <em>baru</em> untuk setiap baris dalam gelung:<pre class="brush:php;toolbar:false">  php // ...
    // Inisialisasi penjejakan baris $ row = 0;
    $ rowElement = $ dom-> createeLement ('div');
    $ rowElement-> setAttribute ('class', 'field-row');
    
    // melangkah ke atas bidang dan membina setiap medan foreach ($ formfields sebagai $ medan) {
      // ...
      // Sekiranya kita mencapai baris baru, buat roweLement $ baru
      jika ($ field-> row> $ row) {
        $ row = $ field-> row;
        $ rowElement = $ dom-> createeLement ('div');
        $ rowElement-> setAttribute ('class', 'field-row');
      }
    
      // membina suis elemen input ($ field-> type) {
        // ...
        // Tambah elemen input ke baris jika ($ input) {
          // ...
          $ rowElement-> appendChild ($ element);
    
          // secara automatik deduplicate $ form-> appendChild ($ rowElement);
        }
      }
    }
    Salin selepas log masuk

    Kami hanya perlu menulis ganti objek $rowElement sebagai elemen DOM baru, yang PHP dirawat sebagai objek unik baru. Oleh itu, pada akhir setiap gelung kita hanya menambah $rowElement semasa - jika ia adalah elemen yang sama dengan lelaran sebelumnya, borang itu dikemas kini;

    Langkah seterusnya

    Borang adalah kes penggunaan yang hebat untuk templat berorientasikan objek. Memandangkan coretan dalam kod teras WordPress, boleh dipertimbangkan bahawa menu bersarang juga merupakan kes penggunaan yang baik. Sebarang tugas yang menandakan logik kompleks adalah calon yang baik untuk pendekatan ini. Domdocument boleh mengeluarkan mana -mana XML, jadi anda juga boleh menggunakannya untuk membina suapan RSS dari data pos.

    Berikut adalah coretan kod lengkap borang kami. Jangan ragu untuk menyesuaikannya dengan apa -apa bentuk API yang anda dapati. Ini adalah dokumentasi rasmi dan sangat berguna untuk memahami API yang ada.

    Kami tidak pernah menyebut bahawa domdocument boleh menghuraikan HTML dan XML sedia ada. Anda kemudian boleh menggunakan API XPath untuk mencari unsur -unsur, yang agak serupa dengan Cheerio pada document.querySelector atau Node.js. Keluk pembelajaran agak curam, tetapi ia adalah API yang sangat kuat untuk mengendalikan kandungan luaran.

    Fakta yang menyeronokkan: Fail Microsoft Office yang berakhir di x (seperti .xlsx) adalah fail XML. Jangan beritahu jabatan pemasaran, tetapi anda boleh menghuraikan dokumen perkataan pada pelayan dan output HTML.

    Perkara yang paling penting ialah mengingati bahawa templat adalah kuasa besar. Mampu membina markup yang tepat untuk keadaan yang betul boleh menjadi kunci untuk mendapatkan pengalaman pengguna yang hebat.

  • Atas ialah kandungan terperinci Membina Borang dalam PHP Menggunakan Domdocument. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

    Artikel sebelumnya:"Disambiguating Tailwind" Artikel seterusnya:Elemen terbina dalam supercharging dengan komponen web "adalah" lebih mudah daripada yang anda fikirkan
    Kenyataan Laman Web ini
    Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
    Isu terkini
    Topik-topik yang berkaitan
    Lagi>
    Cadangan popular
    Tutorial Popular
    Lagi>
    Muat turun terkini
    Lagi>
    kesan web
    Kod sumber laman web
    Bahan laman web
    Templat hujung hadapan