Terkadang Anda ingin istirahat dari rutinitas pengkodean saat ini dan dari masalah kecil yang dikhususkan untuk artikel tentang "detail". Lihatlah apa yang telah Anda lakukan sejak lama. Jadi, visi saya tentang pendekatan terhadap tugas utama pemrograman PHP - menghasilkan halaman web. Saya telah menyentuh sebagian topik ini di beberapa bagian - artikel tentang kelas template dan tentang XML dapat ditemukan di arsip. Sekarang saya ingin menyatukan semuanya dan melakukan sesuatu yang monumental. Bagian pertama.
1. Asal usul php
Di mana sebenarnya php dimulai bagi sebagian besar dari kita? Dari memasukkan script ke halaman HTML. Misalnya, direktori tautan Anda sendiri. Halaman dengan link dari kategori tertentu:
".mysql_result($hasil, 0).""; mysql_free_result($result); $result = mysql_query("PILIH id, judul, rasio, deskripsi, tanggal_situs FROM situs WHERE rubrika=".intval($id). " ORDER BY rasio DESC, tanggal_situs DESC, judul"); if (mysql_error()) echo mysql_error(); else while ($baris = mysql_fetch_assoc($result)) echo " ($baris)
($baris)
Tercatat: ($baris), Nilai: ($baris)
Sederhana dan bersahaja, tetapi yang terpenting adalah kode ini berfungsi. Kesulitan dimulai ketika Anda mencoba menulis nama kategori di judul halaman. Untuk melakukan ini, Anda harus membuat sisipan php di dalam tag
Komplikasi berikutnya adalah upaya untuk bekerja dengan cookie dan mengeluarkannya tergantung pada bagian mana yang dikunjungi pengguna. Untuk lebih membayangkan hal ini: mari kita putuskan bahwa banyak pengunjung akan datang ke beranda kita, dan untuk calon pengiklan kita membuat mesin spanduk dengan penargetan. Katakanlah pengguna yang mengunjungi bagian musik rock dan alat musik akan melihat spanduk yang mengiklankan toko gitar listrik di halaman berikutnya.
Dalam hal ini, kita harus memasukkan kode PHP di awal file dan memindahkan pemeriksaan keberadaan kategori ke sana, karena cookie hanya dapat dikeluarkan sebelum byte pertama dokumen dikeluarkan.
Tentu saja Anda akan mengatakan bahwa hal ini dapat dilakukan dengan mudah menggunakan mekanisme sesi pengguna, yang lebih sederhana dalam hal mengeluarkan konten dan lebih aman karena pengguna dapat mengubah konten cookie secara manual. Ya, ini benar, tapi pertama, ini mewakili visi seorang pemula pemrograman yang membuat halaman beranda, dan kedua, kita berbicara tentang masa lalu - sebenarnya kita berada di tahun 1998.
Itu tidak membuat hidup lebih mudah dengan mengeluarkan blok kode HTML dan PHP yang identik ke dalam file yang disertakan. Tugas yang dijelaskan di atas - membangun katalog sederhana tautan dengan kategori - mungkin merupakan batas atas kemampuan pendekatan ini. Saat melakukan tugas yang lebih kompleks, terdapat risiko yang sangat tinggi untuk menghadapi biaya tenaga kerja yang lebih besar.
2. Rumitnya kode
Perkembangan logis dari pendekatan sebelumnya adalah transisi lengkap ke PHP dalam arti semua halaman adalah kode PHP - di awal file terdapat tag pembuka "
class="club_article_small_caption">Berita untuk klien
($baris)"); if ($baris["tanggal_berita"] > tanggal("Y-m-d", waktu() - 3600*24*14)) print(" baru!"); mencetak(" |
($baris)
($baris) |
Tapi ini tidak menyederhanakan pekerjaan sama sekali, dan saat perhitungan pasti akan tiba: akan ada kebutuhan untuk mengulang desain situs. Perancangnya akan menolak untuk mengedit ini. Hanya orang yang menulis kode tersebut yang dapat memahaminya dan mengganti HTML lama dengan yang baru. Jika orang tersebut tidak lagi mengerjakan proyek tersebut, maka proyek tersebut harus ditulis ulang hampir dari awal atau proyek tersebut akan mati, berubah menjadi monumen kepicikan manusia.
Pilihan lain untuk mengembangkan pendekatan campuran HTML dan PHP. PHP memiliki properti yang disebut advanced-escaping. Ini memungkinkan Anda untuk menampilkan kode HTML biasa di dalam konstruksi bahasa:
Berita untuk klien
=$row["news_date"]?>tanggal("Y-m-d", waktu() - 3600*24*14)) ( ?> baru! | ">
=$row["title"]?>
=$row["announce"]?> |
Perancang atau perancang tata letak, dengan membuka file ini di HomeSite, akan melihat markup HTML dengan penyorotan dan akan dapat mengedit desain halaman. Untuk situs sederhana, cara ini cukup cocok. Dalam situasi yang rumit, hal itu tidak ada gunanya sama sekali.
3. Kudeta
Dengan dirilisnya PHP 3.0... Omong-omong, tidak ada salahnya untuk mengembalikan kronologinya, karena kita berbicara tentang sejarah yang komprehensif. Nah berikut kronologi yang direstore menggunakan arsip milis pengumuman php dan halaman dari arsip web:
08.1997 PHP 3.0 Beta1 06.06.1998 PHP 3.0 Rilis 19.07.1999 PHP 4.0 Beta1 22.05.2000 PHP 4.0 Rilis 12.10.2001 PHP 4.1 Rilis 22.04.2002 PHP 4.2 Rilis 10.10.2002 PHP 4 .3.0pre1 (sebelumnya 1 bukan beta, tapi tetap saja bukan Kandidat Pelepasan)
Jadi, dengan dirilisnya PHP 3.0, muncul alat untuk menerapkan pendekatan baru pada pemrograman PHP - buffering halaman dalam skrip. (Penting untuk dicatat bahwa buffering ini tidak sama seperti yang kita miliki sekarang.)
Seiring berjalannya waktu, tugas membangun website menjadi semakin kompleks, PHP digunakan semakin luas, dan website menjadi semakin dinamis. Semakin besar situsnya, semakin sulit melakukan semuanya menggunakan file yang disertakan dalam campuran PHP dan HTML. Logikanya, langkah selanjutnya dalam ekstensi PHP adalah memproses halaman HTML di memori skrip dan menyajikannya kepada pengguna secara keseluruhan atau sebagian.
Implementasi pendekatan ini setidaknya terbantu oleh dukungan (well, emulasi) pemrograman berorientasi objek yang diimplementasikan dalam PHP3. Telah diciptakan kelas templat, yang memudahkan pengoperasian templat halaman dan data yang harus dimasukkan ke dalamnya.
Hal ini memperluas kemampuan program, namun pada saat yang sama membutuhkan lebih banyak sumber daya sistem. Saat ini kita dapat mengatakan bahwa manfaat menggunakan pendekatan ini melebihi biaya sumber daya sistem, tetapi dua atau tiga tahun yang lalu banyak orang percaya bahwa menyimpan seluruh dokumen dalam memori adalah kemewahan yang tidak terjangkau untuk pemrograman web.
Jadi, secara kiasan, telah terjadi revolusi dalam teknologi: jika sebelumnya PHP bersembunyi di dalam kode HTML dan dengan takut-takut menambahkan informasinya, kini PHP telah menjadi yang teratas dan memegang semua HTML di kakinya.
4. Mengapa kelas template buatan sendiri buruk
Enam bulan kemudian, saya memutuskan untuk mengubah sesuatu dalam rencana saya. Tidak akan ada moralisasi tentang buruknya kelas yang dibuat sendiri. Mereka bagus. Gunakanlah, dan apa yang Anda butuhkan akan menyertai Anda! Ingatlah bahwa beberapa keadaan akan mengganggu Anda.
Pertama. Jika kelas ditulis secara khusus, ini berarti kelas tersebut agak terpisah dari kehidupan. Meskipun kelas tersebut memiliki banyak pengalaman pengembangan di baliknya, namun tetap dibuat dalam kondisi rumah kaca. Teknologi yang dihasilkan akan memiliki kondisi penggunaan spesifiknya sendiri, yang mana perkembangan di masa depan harus disesuaikan, atau kelasnya harus didesain ulang.
Kedua. Sebuah kelas yang disintesis dari pengembangan proyek yang berbeda juga memerlukan perubahan - semakin global, semakin banyak pula perubahannya.
Jadi, Anda bisa membuat kelas sendiri (kelas template, setahu saya banyak orang yang pakai sendiri). Jika Anda melakukannya secara deduktif, membangun kelas berdasarkan perkiraan apa yang Anda perlukan, ada kemungkinan kecil Anda akan mendapatkan sesuatu yang brilian. Dan kemungkinan besar hasilnya tidak sesuai dengan yang Anda butuhkan. Anda dapat menggunakan induksi - kemudian setelah banyak bekerja panjang Anda dijamin mendapatkan sesuatu yang berhasil, tetapi belum tentu brilian.
Hal buruk tentang produk buatan sendiri, yang saya sebutkan di bagian sebelumnya, adalah bahwa dalam kasus pertama ada kemungkinan yang sangat tinggi untuk mendapatkan sesuatu yang salah, tidak berfungsi seperti yang Anda impikan, memerlukan pendekatan khusus dan banyak pengkodean. Dalam kasus kedua, Anda dapat bekerja keras untuk waktu yang lama dan mendapatkan sesuatu yang telah dilakukan dan diterbitkan oleh seseorang sebelum Anda.
Saat membandingkan teknologi, isu utamanya adalah relevansi. Anda dapat membuat situs web yang sangat sederhana menggunakan file yang disertakan dan tidak memikirkan kelas dan mesin. Lebih baik membuat website yang lebih kompleks menggunakan template. Jika kompleksitas meningkat dan pada satu halaman banyak tergantung pada kondisi yang berbeda - menu navigasi tergantung pada status, dll. - lebih baik memikirkan paket XML&XSLT.
Contoh: forum phpBB. Tidak mungkin mengubah desain sepenuhnya sesuai keinginan, karena banyak elemen desain yang tidak ada di template, tetapi di kode PHP. Segala macam formulir login, menu kontrol untuk pengguna yang login, dll. - dimasukkan ke dalam halaman melalui kode PHP, dan bukan sebagai template bersarang. Solusi yang paling populer tidak selalu yang terbaik.
Dmitry Koterov mengomentari pengalamannya mempelajari phpBB: setelah menulis kelas template, banyak orang, dengan penuh semangat, mulai memasukkan semuanya ke dalam kelas ini. Ide dari kelas semacam itu adalah untuk memisahkan kode dan desain, tetapi penulis phpBB, sebaliknya, mencampurkannya sebanyak mungkin.
Namun menurut saya, bahkan dengan implementasi normal dari pendekatan ini (kelas templat), kodenya akan rumit, akan ada banyak file dengan templat. Akhir-akhir ini saya sampai pada kesimpulan bahwa dalam kelas template, pada prinsipnya tidak mungkin memisahkan kode PHP dari data dan desain. Saat mengubah desain situs pada mesin seperti itu, Anda pasti harus mempelajari skrip PHP, dan ini bukan oleh perancangnya, tetapi oleh Anda.
__global__
(disembunyikan dan ditambahkan secara otomatis) |
|||||
blok1 |
|
Dokumentasi mengatakan bahwa tidak perlu menunjukkan dalam templat blok mana yang merupakan anak dari blok mana. Kelas akan memahaminya sendiri.
Dokumentasi untuk kelas ini mengatakan bahwa ia mengetahui bahwa inner1 adalah anak dari blok2, dan tidak perlu menceritakannya tentang hal ini. Untuk memasukkan data ke dalam blok, jalankan saja kode ini sebanyak yang Anda perlukan, baris:
setVariabel(...); $tpl->parseCurrentBlock(); ?>
Untuk menambahkan konten ke blok1, Anda perlu melakukan hal berikut:
setCurrentBlock("batin1"); $tpl->setVariable(...); $tpl->parseCurrentBlock(); $tpl->setVariable(...); $tpl->parseCurrentBlock(); $tpl->mengurai("blok1"); ?>
Hasilnya, kode skripnya terlihat seperti ini:
loadTemplatefile(string nama file [, boolean hapusUnknownVariables, boolean hapusEmptyBlocks]) // menyetel variabel "global", mis. variabel yang tidak termasuk dalam blok (blok anak) $tpl->setVariable(nama variabel string, nilai campuran); // cara lain untuk menentukan variabel adalah melalui array $tpl->setVariable(array (string varname => nilai campuran)); // Kita akan menggunakan beberapa blok, bahkan satu blok yang sangat bersarang di dalam blok lainnya $tpl->setCurrentBlock(string blockname); // Ulangi sebanyak yang diperlukan $tpl->setVariable(array (string varname => nilai campuran)); $tpl->parseCurrentBlock(); // ambil hasilnya atau cetak dengan memanggil $tpl->show() $tpl->get(); ?>
Kode ini lebih nyaman dan jelas dibandingkan dengan FastTemplate.
Namun banyak programmer yang masih menulis kelas template mereka sendiri. Lebih sederhana, namun memiliki beberapa fitur yang tidak ditemukan di kelas umum. Saya menulis kelas saya sendiri di mana saya membuat blok di mana hasil query SQL dimasukkan secara otomatis, selain itu ada kepala dan ekor blok (misalnya, tag
PHP3 memperkenalkan modul untuk fungsi pemrosesan XML. Dengan menggunakan fungsi modul ini, Anda dapat membuat penangan kode XML Anda sendiri, namun, Anda tidak dapat memeriksa validitas dokumen XML.
Penjelasan singkat tentang teori tentang apa itu XML dan mengapa itu diperlukan.
XML adalah cara merekam data terstruktur. "Data terstruktur" biasanya berarti hal-hal seperti spreadsheet, buku alamat, parameter konfigurasi, transaksi keuangan, gambar teknis, dan sebagainya. XML adalah seperangkat aturan (Anda juga dapat menganggapnya sebagai instruksi atau konvensi) untuk mengembangkan format teks yang memungkinkan Anda menyusun data.
Penjelasan tentang apa itu struktur.
Ini adalah bagaimana Anda dapat menulis data terstruktur tentang toko kelontong dalam XML, di mana produk dibagi menjadi beberapa kategori, dan kategori dapat disubordinasikan satu sama lain. Tentu saja data ini dapat ditulis dengan cara yang berbeda, misalnya teks dengan tab sebagai pembatas dan menunjukkan id kategori induk (omong-omong, saat menulis data dalam format XML, seperti terlihat di atas, Anda tidak perlu menentukan dia). XML adalah format siap pakai untuk merekam struktur seperti itu, di dalamnya Anda hanya perlu menyebutkan nama node (tag) dan aturan yang harus dipatuhi oleh struktur tersebut (misalnya, bahwa suatu produk tidak dapat ditempatkan di luar a kategori atau tidak boleh ada lagi kategori tingkat tiga). Lebih jauh:
XML bukanlah bahasa pemrograman, dan Anda tidak perlu menjadi seorang programmer untuk menggunakan atau mempelajarinya. XML memudahkan komputer untuk membuat dan membaca data sekaligus memastikan bahwa strukturnya tidak ambigu. XML menghindari kesalahan desain bahasa umum: XML dapat diperluas, tidak bergantung pada platform, dan mencakup dukungan untuk internasionalisasi dan lokalisasi. XML sepenuhnya sesuai dengan Unicode.
Pengembang PHP menyarankan pemrosesan elemen individual dokumen XML dengan fungsi PHP. Contoh dari manual php:
"B", "EMPHASIS" => "I", "LITERAL" => "TT"); // Berfungsi untuk memulai sebuah tag (dapat menampilkan teks yang kompleks, namun dalam contoh ini // hanya menampilkan tag yang sesuai). function startElement($parser, $name, $attrs) ( global $map_array; if ($htmltag = $map_array[$name]) ( print "<$htmltag>"; ) ) // Fungsi untuk akhir tag function endElement($parser, $name) ( global $map_array; if ($htmltag = $map_array[$name]) ( print "$HTMLTAG>"; ) ) // Fungsi untuk teks (simpul teks) function characterData($parser, $data) ( print $data; ) $xml_parser = xml_parser_create(); // gunakan case-folding agar kita yakin menemukan tag di dalamnya $map_array xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, true); xml_set_element_handler($xml_parser, "startElement", "endElement"); xml_set_character_data_handler($xml_parser, "characterData"); // Membaca file XML if (!($fp = fopen ($file, "r"))) ( die("tidak dapat membuka input XML"); ) while ($data = fread($fp, 4096)) ( if (!xml_parse($xml_parser, $data, feof( $fp))) ( die(sprintf("Kesalahan XML: %s pada baris %d", xml_error_string(xml_get_error_code($xml_parser)), xml_get_current_line_number($xml_parser))); ) ) xml_parser_free($xml_parser); ?>
Contoh ini dapat diperluas dengan menambahkan array nama tag yang akan diproses secara berbeda dan kondisi yang sesuai dalam fungsi startElement dan endElement.
Kodenya terlihat sangat buruk. Praktis tidak cocok untuk digunakan dalam mengubah XML menjadi halaman HTML, meskipun telah digunakan di beberapa tempat, misalnya di situs How IT works. Tentu saja, Anda dapat menulis automator Anda sendiri yang akan membaca file konfigurasi dan membuat array, namun dalam hal total biaya tenaga kerja, akan lebih menguntungkan menggunakan kelas template yang kuat seperti Smarty.
Pengerjaan proyek ini dimulai pada tahun 1999, ketika sekelompok pengembang mulai menulis spesifikasi mesin template. Setelah menentukan apa yang harus dilakukan, para pengembang mencoba menulis modul dalam C, namun pada akhirnya mereka memutuskan bahwa lebih baik membuat kelas dalam PHP yang dapat diakses dan dimengerti oleh semua pengembang situs web.
Sekarang Smarty adalah salah satu proyek PHP, situs webnya terletak di server PHP di smarty.php.net.
Secara formal, Smarty adalah kelas template. Faktanya, fungsionalitasnya jauh lebih tinggi daripada kumpulan *Templat.
Pertama, Smarty tidak hanya memasukkan variabel ke dalam template, tetapi juga mengeksekusi kode PHP di dalam template itu sendiri. Kedua, templat di Smarty diubah menjadi skrip PHP, dan semua pekerjaan kotor memasukkan variabel ke dalam teks dan menjalankan konstruksi logis diberikan ke parser PHP bawaan. Ketika caching diaktifkan, skrip PHP ini disimpan ke dalam file yang dipanggil saat templat diakses lagi. Saat templat berubah, skrip dibuat lagi. Caching ini secara signifikan mempercepat kerja skrip.
Smarty juga dapat memproses konstruksi logis if-else yang ada di dalam templat, mengubahnya menjadi kode PHP. Konstruksi yang disebut pengubah variabel diproses dengan cara yang sama. Mereka memungkinkan Anda untuk menghapus beberapa fungsi dari skrip utama, memindahkannya ke template dan skrip PHP yang di-cache.
(*Tulis judul dengan huruf kapital*)
($judul|atas),
(* Persingkat topik menjadi 40 karakter dengan meletakkan... di akhir *) Topik: ($topic|truncate:40:"...")Teks ini diubah menjadi kode ini:
_run_mod_handler("atas", benar, $ini->_tpl_vars["Nama"]); ?> Topik:_run_mod_handler("memotong", benar, $ini->_tpl_vars["Nama"], 40, "..."); ?>
Satu set variabel bawaan seperti $smarty.now (waktu saat ini) juga tersedia. Gambaran indah ini dilengkapi dengan keluaran jendela debugging yang berisi nilai variabel, pemanggilan templat bersarang, dan dukungan untuk filter dan plugin masukan/keluaran khusus.
Semuanya akan baik-baik saja jika Smarty berukuran lebih kecil. Sekarang (versi 2.3.1) “berbobot” 144 kilobyte dan berjalan sangat lambat pada AMD K6 266 MHz. Pengembang yang cerdas merekomendasikan penggunaan Zend Accelerator atau PHP Accelerator.
DOM saat ini adalah kata terakhir dalam templat dokumen di PHP. Saya menjelaskan modulnya di artikel “XML: Spesifikasi dan Fungsi DOM di PHP”.
Meskipun bertele-tele dan sejumlah besar kode melakukan operasi yang cukup sederhana, DOM XML memiliki banyak harapan.
Kerugian utama dari pendekatan tekstual untuk mengedit dokumen XML (tentu saja mengedit dalam skrip) adalah Anda perlu membaca spesifikasi XML dengan cermat atau tidak sepenuhnya yakin dengan apa yang terjadi pada akhirnya.
Misalnya, memasukkan teks ke dalam node adalah tugas yang sederhana. Namun, dalam dokumen XML, karakter layanan dan karakter tabel non-ISO harus dikonversi ke entitas XML (<) или в номера символов UTF-8 (&x0442;). В модуле DOM XML достаточно сконвертировать текст в UTF-8 и вызвать метод create_text_node.
Situs saya masih menjalankan mesin lama yang menghasilkan string teks, dan terkadang melakukan trik menarik dengan dokumen yang bentuknya tidak bagus. Selain itu, objek dapat diteruskan sebagai parameter ke suatu fungsi, dan nama metode yang dipanggil dapat dijadikan variabel.
Terakhir, keunggulan utama DOM XML adalah tidak adanya modul biner untuk pemrosesan teks dokumen dalam PHP. Ini berarti Anda harus menulis parsernya sendiri.
Sedangkan untuk jumlah kode yang besar, hal ini cukup wajar. Lagi pula, jika Anda ingin mengedit dokumen melalui teks, tulis ekspresi reguler dan gunakan serangkaian fungsi string. Anda juga memerlukan banyak kode ini jika mengikuti konvensi XML.
Operasi dengan dokumen melalui DOM perlu dikelompokkan ke dalam fungsinya sendiri, yaitu kelas templat DOM harus dibuat.
Anda dapat memasukkan data umum ke situs atau bagian-bagiannya ke dalam templat terpisah. Selebihnya akan dimasukkan ke dalam dokumen menggunakan teknik yang saya jelaskan:
$root1 = $dom1->elemen_dokumen(); $anak = $root1->child_nodes(); $root2 = $dom2->document_element(); untuk ($i = 0; $i< sizeof($child); $i++) $root2->append_child($anak[$i]->clone_node()); ?>
Anda dapat membuat skrip sederhana untuk situs tempat permintaan dokumen akan dialihkan. Berikut ini ditulis dalam .htaccess:
Opsi FollowSymLinks RewriteEngine On # memeriksa keberadaan file dengan nama yang sama # dan ekstensi phpxml untuk root bagian RewriteCond %(DOCUMENT_ROOT)/$1/index.phpxml -f # jika file seperti itu ada, aturan dipicu RewriteRule ^(+)/?$ /$1 /index.php # aturan ini akan berfungsi untuk alamat # yang ditulis ulang dengan aturan sebelumnya, dan untuk # file lainnya, mengirimkan permintaan ke skrip composer.php. RewriteCond %(DOCUMENT_ROOT)/$1.phpxml -f Aturan Penulisan Ulang ^(+)\.php$ /composer.php [L]
Script composer.php akan membuka file dengan nama yang sama seperti yang diminta, tetapi dengan ekstensi phpxml. Server Apache telah memeriksa keberadaan file ini saat memproses aturan.
6.1 Validasi dokumen
Ini adalah alat yang seharusnya menggantikan atau secara signifikan menggantikan alat verifikasi data buatan sendiri. Sekarang sudah menjadi mode untuk meninggalkan database dan menyimpan data dalam file.
Dengan basisnya sederhana: Anda mendapatkan array dan membuat string teks darinya (menggunakan loop atau kelas templat seperti php-template), atau mendapatkan string menggunakan pohon objek sql2xml (atau lagi string). Lebih sulit untuk bekerja dengan file, karena disarankan untuk memeriksa integritas data untuk berjaga-jaga.
Ada dua pendekatan untuk membuat markup. Yang pertama adalah markup yang berpusat pada data, yang kedua adalah markup yang berpusat pada dokumen.
Contoh markup berorientasi data:
Dua tingkat hierarki - baris + bidang (tentu saja, jika ada 3 atau 4, tidak ada yang berubah secara kualitatif), secara umum sama dengan kueri dari database yang diformat menggunakan sql2xml. Contoh markup berorientasi dokumen:
Opsi ini ditulis dalam bahasa manusia bebas, namun data dalam elemen acro dan title tetap sama; keduanya dapat diperoleh dari dokumen menggunakan kueri XPath atau XQuery yang sama: /kejuaraan/kejuaraan/gelar Opsi markup pertama dapat direpresentasikan sebagai tabel database. Anda dapat memperumitnya, misalnya - sebuah fragmen dokumen:
Hal ini tidak akan menghentikan dokumen untuk menjadi data-sentris. Sebuah dokumen baru dapat direpresentasikan sebagai 2 tabel, digabungkan ketika ditanyakan menggunakan operator LEFT JOIN.
Dokumen kedua memiliki struktur yang lebih kompleks, dan secara umum tidak mungkin untuk menjejalkannya ke dalam sebuah tabel.
Omong-omong, inilah perbedaan utama antara database XML dan database non-XML. Basis data XML juga berfungsi dengan markup berorientasi dokumen (tidak hanya hasilnya ditampilkan dalam XML). Markup data-sentris dapat disimpan dalam database relasional, dan outputnya dapat diformat menggunakan utilitas seperti sql2xml.
Jadi, kembali ke validasi dokumen, perlu dicatat bahwa markup berorientasi dokumen sangat sulit untuk diperiksa kepatuhannya terhadap skema DTD atau XML dengan parser string sederhana.
Contoh lainnya adalah markup formulir di kelas TXF saya:
Saya menguji ini melalui skema DTD. Memeriksa kepatuhan skema dokumen adalah fitur standar perpustakaan XML DOM.
Untuk format pertukaran data yang umum digunakan, seperti RSS, terdapat spesifikasi dan skema DTD (skema XML). Untuk menghindari kerumitan menulis parser RSS Anda sendiri, Anda cukup menambahkan skema ke dokumen dan memeriksa validitasnya. Kemudian ambil node yang diperlukan dari dokumen menggunakan ekspresi get_content atau XPath.
6.2 Penyimpangan liris
Saya terpaksa menyelesaikan penulisan bagian seri ini dengan artikel Spectator terbaru yang berjudul “PHP Templates for Dummies.”
Panggilan untuk melupakan kata-kata seperti XML, XHTML "dan X lainnya...", di sepanjang jalan memberikan tendangan yang layak untuk Smarty, dan, menyelesaikan dadakannya, meminta orang-orang pintar untuk bercukur dengan pisau cukur Occam.
Pisau cukur yang malang! Mereka mengibarkannya di spanduk, melambaikannya ke mana pun mereka bisa, menyodoknya dan mencoba melukai lawan mereka dengan itu.
Sialan pisau cukurnya! Persetan dengan aturan bodoh ini “untuk tidak menghasilkan entitas melebihi apa yang diperlukan.” Ini adalah kebenaran yang terlalu usang untuk diingat orang, dan umumnya tidak cocok untuk mengevaluasi orang lain. Jumlah “ekstra yang diperlukan” berbeda-beda untuk setiap orang. Pelanggan situs mungkin berkata: "Mengapa saya membutuhkan skrip Anda? Buatlah dalam HTML sederhana sehingga kita dapat mengeditnya nanti dengan FrontPage! Pernahkah Anda membaca tentang pisau cukur Occam?"
Saya sudah lama percaya bahwa alasan utama penggunaan teknologi baru dalam pemrograman adalah skala ekonomi. Seperti yang mereka tulis kepada saya di komentar di artikel lama, “seiring dengan bertambahnya volume situs, Anda akan tenggelam dalam template Anda.” Dan dalam artikel saya, saya menekankan hal ini - mereka berkata, tolong, main-main dengan penyertaan rumit Anda dan kode yang dicampur dengan HTML, ini akan menghalangi ketika Anda perlu melakukan banyak kode program.
Sebenarnya ada alasan lain. Ini adalah keterampilan yang dimiliki setiap individu. Mereka yang mengetahui XML, XSLT dan XPath dengan baik, atau dapat dengan cepat menemukan solusi untuk masalah di lingkungan ini, dalam banyak kasus akan menyelesaikan proyek menggunakan teknologi XML. Akan mudah dan sederhana baginya untuk melakukan ini, karena dia tahu bagaimana melakukannya dengan baik. Mereka yang tidak tahu atau tidak tahu dengan baik akan melakukannya dengan cara yang “umum”.
Satu-satunya pertanyaan yang tersisa adalah apakah solusinya yang menggunakan teknologi XML akan lebih efektif dibandingkan jika dia melakukannya menggunakan kelas templat atau campuran PHP&HTML? Ya mereka akan. Izinkan saya memberi Anda perbandingan alegoris.
Pernahkah Anda melihat bagaimana pemain berpengalaman dan “lamers” bermain bola voli? Tim "bola" melempar bola ke sisi lain, dengan cara hook atau crook, sehingga lawan menjatuhkan bola ke dirinya sendiri. Mereka tidak tahu bagaimana melakukan serangan ofensif, dan, dipandu oleh pepatah pisau cukur, mereka bermain dengan sederhana. Seorang pemain berpengalaman bisa melempar bola jauh lebih baik daripada seorang baller. Namun, dia akan mencapai hasil yang lebih besar jika dia melakukan serangan menyerang dengan baik.
Jika Anda memiliki pertanyaan lain atau ada sesuatu yang tidak jelas - selamat datang di kami | |
|
5 Februari , 2017
Saya tidak tahu kerangka PHP apa pun. Hal ini menyedihkan dan memalukan, namun belum dilarang oleh undang-undang. Tetapi pada saat yang sama saya ingin bermain-main dengan REST API. Soalnya php secara default hanya mendukung $_GET dan $_POST. Dan untuk layanan RESTful Anda juga harus bisa bekerja dengan PUT, DELETE dan PATCH. Dan tidak terlalu jelas bagaimana memproses banyak permintaan seperti itu secara budaya DAPATKAN http://site.ru/users, HAPUS http://site.ru/goods/5 dan kata-kata kotor lainnya. Bagaimana cara menggabungkan semua permintaan tersebut menjadi satu titik, menguraikannya secara universal menjadi beberapa bagian dan menjalankan kode yang diperlukan untuk memproses data?
Hampir semua framework PHP dapat melakukan hal ini secara langsung. Misalnya Laravel, di mana routing diimplementasikan dengan jelas dan sederhana. Namun bagaimana jika kita tidak perlu mempelajari topik besar baru saat ini, namun hanya ingin segera memulai proyek dengan dukungan REST API? Ini akan dibahas dalam artikel.
Apa yang bisa dilakukan oleh layanan RESTful kami?
1. Mendukung semua 5 jenis permintaan utama: GET, POST, PUT, PATCH, DELETE.
2. Selesaikan berbagai rute tampilan
POS /barang
PUT /barang/(Id bagus)
DAPATKAN /pengguna/(userId)/info
dan rantai panjang sewenang-wenang lainnya.
Perhatian: artikel ini bukan tentang dasar-dasar REST API
Saya berasumsi Anda sudah familiar dengan pendekatan REST dan memahami cara kerjanya. Jika tidak, maka ada banyak artikel bagus di Internet tentang dasar-dasar REST - Saya tidak ingin menduplikasinya, ide saya adalah menunjukkan cara bekerja dengan REST dalam praktik.
Fungsi apa yang akan kami dukung?
Mari kita pertimbangkan 2 entitas - produk dan pengguna.
Untuk produk, pilihannya adalah sebagai berikut:
- 1. DAPATKAN /barang/(goodId)— Memperoleh informasi tentang produk
- 2. POS /barang— Menambahkan produk baru
- 3. PUT /barang/(Id bagus)— Mengedit produk
- 4. PATCH /barang/(Id bagus)— Mengedit beberapa parameter produk
- 5. HAPUS /barang/(goodId)— Menghapus produk
Bagi pengguna, untuk variasi, mari pertimbangkan beberapa opsi dengan GET
- 1. DAPATKAN /pengguna/(ID pengguna)— Informasi lengkap tentang pengguna
- 2. DAPATKAN /pengguna/(userId)/info— Hanya informasi umum tentang pengguna
- 3. DAPATKAN /pengguna/(userId)/pesanan— Daftar pesanan pengguna
Bagaimana cara kerjanya dengan PHP asli?
Hal pertama yang akan kita lakukan adalah menyiapkan .htaccess sehingga semua permintaan dialihkan ke file index.php. Dialah yang akan terlibat dalam ekstraksi data.
Kedua, mari kita tentukan data apa yang kita butuhkan dan tulis kode untuk mendapatkannya - di index.php.
Kami tertarik pada 3 jenis data:
- 1. Metode permintaan (GET, POST, PUT, PATCH atau DELETE)
- 2. Data dari URL, misalnya, pengguna/(userId)/info - ketiga parameter diperlukan
- 3. Data dari badan permintaan
.htaccess
Mari buat file .htaccess di root proyek
RewriteEngine Pada RewriteCond %(REQUEST_FILENAME) !-f RewriteRule ^(.+)$ index.php?q=$1
Dengan baris misterius ini kami perintahkan Anda untuk melakukan ini:
1 - kirim semua permintaan apa pun ke file raja index.php
2 - buat string di URL tersedia di index.php di parameter get q. Artinya, data dari URL seperti /pengguna/(IDpengguna)/info kita akan mendapatkan dari $_GET["q"].
indeks.php
Mari kita lihat index.php baris demi baris. Pertama, mari kita dapatkan metode permintaannya.
// Tentukan metode permintaan $method = $_SERVER["REQUEST_METHOD"];
Kemudian data dari badan permintaan
// Dapatkan data dari isi permintaan $formData = getFormData($method);
Untuk GET dan POST, mudah untuk mengambil data dari array $_GET dan $_POST yang sesuai. Namun untuk cara lainnya perlu sedikit mesum. Kode untuk mereka diambil dari aliran php://masukan, kodenya mudah untuk Google, saya baru saja menulis pembungkus umum - fungsi getFormData($method)
// Mendapatkan data dari badan permintaan fungsi getFormData($method) ( // GET atau POST: mengembalikan data apa adanya ($method === "GET") return $_GET; if ($method === "POST" ) return $_POST; // PUT, PATCH atau DELETE $data = array(); $exploded = meledak("&", file_get_contents("php://input")); foreach($meledak sebagai $pair) ( $ item = meledak("=", $pair); if (count($item) == 2) ( $data = urldecode($item); ) ) kembalikan $data; )
Artinya, kami mendapatkan data yang diperlukan dengan menyembunyikan semua detail di getFormData - bagus sekali. Mari beralih ke bagian yang paling menarik - perutean.
// Parsing url $url = (isset($_GET["q"])) ? $_GET["q"] : ""; $url = rtrim($url, "/"); $url = meledak("/", $url);
Kita telah mempelajari di atas bahwa .htaccess akan memasukkan parameter dari URL ke dalam q-parameter array $_GET. Artinya, $_GET["q"] akan berisi sesuatu seperti ini: pengguna/10. Terlepas dari metode mana yang kami gunakan untuk menjalankan permintaan.
A meledak("/", $url) mengubah string ini menjadi array untuk kita, yang sudah dapat kita gunakan. Jadi, buatlah rangkaian pertanyaan sepanjang yang Anda inginkan, misalnya,
DAPATKAN /barang/halaman/2/batas/10/sort/price_asc
Dan yakinlah, Anda akan menerima sebuah array
$urls = array("barang", "halaman", "2", "batas", "10", "sortir", "price_asc");
Sekarang kita memiliki semua datanya, kita perlu melakukan sesuatu yang berguna dengannya. Dan hanya 4 baris kode yang bisa melakukannya
// Tentukan data router dan url $router = $urls; $urlData = array_slice($url, 1); // Hubungkan file router dan jalankan fungsi utama include_once "routers/" . $router. ".php"; rute($metode, $urlData, $formData);
Apa kau mengerti? Kami membuat folder router tempat kami meletakkan file yang memanipulasi satu entitas: produk atau pengguna. Pada saat yang sama, kami setuju bahwa nama file bertepatan dengan parameter pertama di urlData - itu adalah router, $router. Dan router ini perlu dihapus dari urlData, kita tidak membutuhkannya lagi dan hanya digunakan untuk menghubungkan file yang diperlukan. array_slice($url, 1) dan akan memberi kita semua elemen array kecuali yang pertama.
Sekarang yang tersisa hanyalah menghubungkan file router yang diinginkan dan menjalankan fungsi rute dengan tiga parameter. Apa rute fungsi ini? Mari kita sepakat bahwa di setiap file router akan ditentukan suatu fungsi yang, berdasarkan parameter input, akan menentukan tindakan apa yang dimulai pengguna dan akan mengeksekusi kode yang diperlukan. Sekarang hal ini akan menjadi lebih jelas. Mari kita pertimbangkan permintaan pertama - memperoleh data tentang suatu produk.
DAPATKAN /barang/(goodId)
File router/barang.php
// Fungsi router rute($method, $urlData, $formData) ( // Mendapatkan informasi tentang suatu produk // GET /goods/(goodId) if ($method === "GET" && count($urlData) == = 1) ( // Dapatkan id produk $goodId = $urlData; // Keluarkan produk dari database... // Keluarkan respon ke klien echo json_encode(array("method" => "GET", "id" => $goodId, "good" => "phone", "price" => 10000)); return; ) // Mengembalikan header kesalahan("HTTP/1.0 400 Permintaan Buruk"); echo json_encode(array ("kesalahan" => "Permintaan Buruk" ")); )
Isi file adalah satu fungsi rute besar, yang, bergantung pada parameter yang diteruskan, melakukan tindakan yang diperlukan. Jika metode GET dan 1 parameter (goodId) diteruskan ke urlData, maka ini adalah permintaan untuk mendapatkan data tentang suatu produk.
Perhatian: contohnya sangat disederhanakan
Dalam kehidupan nyata, tentunya Anda juga perlu memeriksa parameter input, misalnya goodId adalah angka. Daripada menulis kode di sini, Anda mungkin akan menyertakan kelas yang diperlukan. Dan untuk menerima produk, buat objek kelas ini dan panggil beberapa metode di dalamnya.
Atau mungkin Anda dapat mentransfer kendali ke beberapa pengontrol, yang sudah menangani inisialisasi model yang diperlukan. Ada banyak pilihan, kami hanya mempertimbangkan struktur umum kode.
Sebagai tanggapan kepada klien, kami menampilkan data yang diperlukan: nama produk dan harganya. Id dan metode produk sepenuhnya opsional dalam aplikasi nyata. Kami menampilkannya hanya untuk memastikan bahwa metode yang benar dipanggil dengan parameter yang benar.
Mari kita coba dengan sebuah contoh: buka konsol browser Anda dan jalankan kodenya
$.ajax((url: "/examples/rest/goods/10", metode: "GET", tipe data: "json", sukses: function(response)(console.log("response:", respon))) )
Kode akan mengirimkan permintaan ke server tempat saya menerapkan aplikasi serupa dan mengeluarkan respons. Pastikan rute yang Anda minati adalah /barang/10 benar-benar berhasil. Pada tab Jaringan Anda akan melihat permintaan yang sama.
Dan ya, /examples/rest adalah jalur root aplikasi pengujian kami ke situs
Jika Anda lebih terbiasa menggunakan curl di konsol, jalankan ini di terminal - jawabannya akan sama, dan bahkan dengan header dari server.
Curl -X DAPATKAN https://site/examples/rest/goods/10 -i
Di akhir fungsi kami menulis kode berikut.
// Mengembalikan header kesalahan("HTTP/1.0 400 Permintaan Buruk"); echo json_encode(array("error" => "Permintaan Buruk"));
Artinya jika kami melakukan kesalahan dengan parameter atau rute yang diminta tidak ditentukan, kami akan mengembalikan kesalahan 400 Permintaan Buruk ke klien. Misalnya, tambahkan sesuatu seperti ini ke URL: barang/10/param_lainnya dan Anda akan melihat kesalahan di konsol dan respons 400 - permintaan yang bengkok tidak berhasil.
Berdasarkan kode http respons server
Kami tidak akan repot-repot mengeluarkan kode yang berbeda, meskipun hal ini layak dilakukan menurut REST. Ada banyak kesalahan klien. Bahkan dalam kasus sederhana kita, 405 sesuai jika metode yang diberikan salah. Saya tidak ingin mempersulit keadaan dengan sengaja.
Jika berhasil, server kami akan selalu mengembalikan 200 OK. Untungnya, saat membuat sumber daya, Anda harus memberikan 201 Created. Namun sekali lagi, dalam hal penyederhanaan, kami akan membuang seluk-beluk ini, tetapi dalam proyek nyata Anda dapat dengan mudah menerapkannya sendiri.
Sejujurnya, artikel ini sudah selesai. Saya rasa Anda sudah memahami pendekatannya, bagaimana semua rute diselesaikan, data diambil, cara mengujinya, cara menambahkan permintaan baru, dll. Namun untuk melengkapi gambarnya, saya akan memberikan implementasi dari 7 kueri tersisa yang kami uraikan di awal artikel. Sepanjang jalan, saya akan membuat beberapa komentar menarik, dan pada akhirnya saya akan memposting arsip dengan kode sumbernya.
POS /barang
Menambahkan produk baru
// Menambahkan produk baru // POST /goods if ($method === "POST" && blank($urlData)) ( // Menambahkan produk ke database... // Keluarkan respons ke klien echo json_encode (array("metode" => "POST", "id" => rand(1, 100), "formData" => $formData)); kembali; )
urlData sekarang kosong, tetapi formData digunakan - kami hanya akan menampilkannya ke klien.
Bagaimana cara melakukannya dengan "benar"?
Menurut kanon REST, dalam permintaan posting Anda harus mengembalikan hanya id entitas yang dibuat atau url yang dapat digunakan untuk memperoleh entitas ini. Artinya, jawabannya hanya berupa angka - (Id bagus), atau /barang/(Id bagus).
Mengapa saya menulis "benar" dalam tanda kutip? Ya, karena REST bukanlah seperangkat aturan ketat, melainkan rekomendasi. Dan bagaimana Anda akan menerapkannya tergantung pada preferensi Anda atau perjanjian yang sudah diterima mengenai proyek tertentu.
Ingatlah bahwa pemrogram lain yang membaca kode dan mengetahui pendekatan REST akan mengharapkan respons terhadap permintaan posting id dari objek yang dibuat atau url dari mana data tentang objek ini dapat diambil dengan permintaan get.
Menguji dari konsol
$.ajax((url: "/examples/rest/goods/", metode: "POST", data: (bagus: "notebook", harga: 20000), tipe data: "json", sukses: function(response)( console.log("respon:", tanggapan))))
Curl -X POST https://site/examples/rest/goods/ --data "good=notebook&price=20000" -i
PUT /barang/(Id bagus)
Mengedit produk
// Perbarui semua data produk // PUT /goods/(goodId) if ($method === "PUT" && count($urlData) === 1) ( // Dapatkan id produk $goodId = $urlData; / / Perbarui semua kolom produk di database... // Keluarkan respons ke klien echo json_encode(array("method" => "PUT", "id" => $goodId, "formData" => $formData)) ; kembali; )
Di sini semua data sudah terpakai secara maksimal. Id produk ditarik dari urlData, dan properti dari formData.
Menguji dari konsol
$.ajax((url: "/examples/rest/goods/15", metode: "PUT", data: (bagus: "notebook", harga: 20000), tipe data: "json", sukses: fungsi(respons) (konsol.log("respons:", respons))))
Curl -X PUT https://site/examples/rest/goods/15 --data "good=notebook&price=20000" -i
PATCH /barang/(Id bagus)
Pembaruan produk sebagian
// Pembaruan sebagian data produk // PATCH /goods/(goodId) if ($method === "PATCH" && count($urlData) === 1) ( // Dapatkan id produk $goodId = $urlData; // Kami hanya memperbarui kolom produk tertentu di database... // Menampilkan respons ke klien echo json_encode(array("method" => "PATCH", "id" => $goodId, "formData" => $formData)); kembali; )
Menguji dari konsol
$.ajax((url: "/examples/rest/goods/15", metode: "PATCH", data: (harga: 25000), tipe data: "json", sukses: function(response)(console.log(" tanggapan:", tanggapan))))
Curl -X PATCH https://site/examples/rest/goods/15 --data "harga=25000" -i
Mengapa harus pamer dengan PUT dan PATCH?
Bukankah satu PUT saja sudah cukup? Bukankah mereka melakukan tindakan yang sama - memperbarui data objek?
Itu benar - secara lahiriah, tindakannya adalah satu. Perbedaannya terletak pada data yang dikirimkan.
PUT berasumsi demikian Semua bidang objek, dan PATCH - saja berubah. Yang dikirim di badan permintaan. Harap dicatat bahwa pada PUT sebelumnya kami menyampaikan nama produk dan harga. Dan di PATCH - hanya harganya. Artinya, kami hanya mengirimkan data yang diubah ke server.
Apakah Anda memerlukan PATCH - putuskan sendiri. Tapi ingat programmer pembaca kode yang saya sebutkan di atas.
HAPUS /barang/(goodId)
Menghapus produk
// Menghapus produk // HAPUS /goods/(goodId) if ($method === "DELETE" && count($urlData) === 1) ( // Dapatkan id produk $goodId = $urlData; // Hapus produk dari database... // Keluarkan respons ke klien echo json_encode(array("method" => "DELETE", "id" => $goodId)); return; )
Menguji dari konsol
$.ajax((url: "/examples/rest/goods/20", metode: "DELETE", tipe data: "json", sukses: function(response)(console.log("response:", respon))) )
Curl -X HAPUS https://site/examples/rest/goods/20 -i
Semuanya jelas dengan permintaan DELETE. Sekarang mari kita lihat bekerja dengan pengguna - router pengguna dan, karenanya, file pengguna.php
DAPATKAN /pengguna/(ID pengguna)
Mengambil semua data pengguna. Jika permintaan GET seperti /pengguna/(ID pengguna), maka kami akan mengembalikan semua informasi tentang pengguna jika ditentukan tambahan /info atau / pesanan, maka, masing-masing, hanya informasi umum atau daftar pesanan.
// Fungsi router rute($method, $urlData, $formData) ( // Mendapatkan semua informasi tentang pengguna // GET /users/(userId) if ($method === "GET" && count($urlData) = = = 1) ( // Dapatkan id produk $userId = $urlData; // Ekstrak semua data tentang pengguna dari database... // Keluarkan respons ke klien echo json_encode(array("method" => " DAPATKAN", "id" = > $userId, "info" => array("email" => " [dilindungi email]", "nama" => "Webdevkin"), "pesanan" => array(array("orderId" => 5, "summa" => 2000, "orderDate" => "01/12/2017"), array (" orderId" => 8, "summa" => 5000, "orderDate" => "03/02/2017")))); return; ) // Mengembalikan header kesalahan("HTTP/1.0 400 Permintaan Buruk" ); echo json_encode( array("kesalahan" => "Permintaan Buruk")); )
Menguji dari konsol
$.ajax((url: "/examples/rest/users/5", metode: "GET", tipe data: "json", sukses: function(response)(console.log("response:", respon))) )
Curl -X DAPATKAN https://site/examples/rest/users/5 -i
DAPATKAN /pengguna/(userId)/info
Informasi umum tentang pengguna
// Mendapatkan informasi umum tentang pengguna // GET /users/(userId)/info if ($method === "GET" && count($urlData) === 2 && $urlData === "info") ( // Dapatkan id produk $userId = $urlData; // Ekstrak data umum tentang pengguna dari database... // Keluarkan respon ke klien echo json_encode(array("method" => "GET", "id " => $userId, " info" => array("email" => " [dilindungi email]", "nama" => "Webdevkin"))); kembali; )
Menguji dari konsol
$.ajax((url: "/examples/rest/users/5/info", metode: "GET", tipe data: "json", sukses: function(response)(console.log("response:", respon) )))
Curl -X DAPATKAN https://site/examples/rest/users/5/info -i
DAPATKAN /pengguna/(userId)/pesanan
Mendapatkan daftar pesanan pengguna
// Menerima pesanan pengguna // GET /users/(userId)/orders if ($method === "GET" && count($urlData) === 2 && $urlData === "orders") ( // Dapatkan product id $userId = $urlData; // Ekstrak data tentang pesanan pengguna dari database... // Keluarkan respon ke klien echo json_encode(array("method" => "GET", "id" => $ userId, "orders" => array(array("orderId" => 5, "summa" => 2000, "orderDate" => "01/12/2017"), array("orderId" => 8, "summa " => 5000,"tanggal pemesanan " => "03/02/2017")))); kembali; )
Menguji dari konsol
$.ajax((url: "/examples/rest/users/5/orders", metode: "GET", tipe data: "json", sukses: function(response)(console.log("response:", respon) )))
Curl -X DAPATKAN https://site/examples/rest/users/5/orders -i
Hasil dan sumber
Sumber dari contoh artikel -
Seperti yang Anda lihat, mengatur dukungan REST API di php asli ternyata tidak terlalu sulit dan sepenuhnya legal. Yang utama adalah dukungan untuk rute dan metode PHP non-standar PUT, PATCH dan DELETE.
Kode utama yang mengimplementasikan dukungan ini cocok dengan 3 lusin baris index.php. Selebihnya hanyalah sebuah harness yang dapat diimplementasikan sesuka Anda. Saya menyarankan melakukan ini dalam bentuk file router plug-in, yang namanya sesuai dengan entitas proyek Anda. Tapi Anda bisa menggunakan imajinasi Anda dan menemukan solusi yang lebih menarik.
Pertama, kami akan menyempurnakan halaman pendaftaran dengan menambahkan kemampuan untuk mengunggah avatar. Gambar sumber harus dalam format jpg, gif atau png. Ukurannya juga tidak boleh lebih dari 2 MB. Tenang saja, setelah dikompres scriptnya, ukuran avatarnya akan menjadi sekitar 3 kb dan berformat jpg. Buka halamannya Reg.php dan menambahkannya ke dalam tag < membentuk> garis enctype="multibagian/form-data", seperti pada contoh: