Pada dua pertemuan sebelumnya kita telah menyelesaikan proses pemeriksaan untuk semua peraturan yang kita buat. Kita juga telah mengubah beberapa tipe inputan pada form HTML menjadi type="text"
untuk mempermudah pemeriksaan.
Pada pertemuan kali ini, kita akan melanjutkan proses validasi form tersebut. Yaitu dengan membuat pesan error dan menampilkannya di halaman form HTML.
Siapkan senjata, nyamankan tempat duduk, seduh kopi.
Karena kita akan mulai kembali menulis kode.
Mempersingkat Kode
Sebelum kita mulai membuat pesan error. Terlebih dahulu kita akan merapikan dan memepersingkat kode dari fungsi validasi()
.
Pada kode program sebelumnya, ketika kita ingin memanggil fungsi pemeriksaan, kita selalu melakukan logika percabangan dengan perintah if
untuk memanggil fungsi pemeriksaan yang sesuai:
- Untuk peraturan “required” kita panggil fungsi
lolosRequired()
. - Untuk peraturan “numeric” kita panggil fungsi
lolosNumeric()
. - Untuk peraturan “url” kita panggil fungsi
lolosUrl()
.
Lalu bagaimana jika fungsi pemeriksaannya ada banyak sekali? Apakah kita juga akan menulis if-else
sebanyak peraturan yang ada?
Berhubung nama fungsi dan nama peraturan memiliki pola yang jelas:
- Yaitu nama fungsi selalu diawali kata “lolos”.
- Nama fungsi selalu diikuti nama peraturan yang huruf pertamanya telah dibuat kapital.
- Sehingga nama fungsi bisa kita generate menggunakan kode program.
- Dengan begitu kita tidak perlu melakukan
if-else
secara manual.
Langsung saja buka file helper/fungsi-validasi.php
.
Masuk ke fungsi validasi()
.
Hapus semua kode pada foreach()
ke dua, lalu timpa dengan kode yang baru seperti berikut:
<?php
function validasi(array $listInput)
{
...
foreach ($listInput as $input => $listPeraturan) {
...
foreach ($listPeraturan as $peraturan) {
echo "-> Peraturan <strong>{$peraturan}</strong>: ";
$namaFungsi = 'lolos' . ucfirst($peraturan);
echo "Panggil fungsi <strong>{$namaFungsi}</strong>";
echo "<br>";
}
...
}
}
Jalankan halaman web, klik tombol Sumbit. Kita akan mendapatkan output kira-kira sebagai berikut:
Pada output di atas, kita telah berhasil membuat variabel $namaFungsi
yang berisi nama fungsi pemeriksaan yang akan kita panggil sesuai dengan isi dari variabel $peraturan
.
Memanggil fungsi pemeriksaan secara dinamis
Setelah berhasil membuat variabel $namaFungsi
. Kita bisa langsung memanggil fungsi yang sesuai secara dinamis dengan menambahkan tanda kurung ()
setelah variabel $namaFungsi()
.
<?php
$namaFungsi = "lolosUrl";
$namaFungsi("https://jagongoding.com");
Kode program di atas akan memanggil fungsi apa pun yang sesuai dengan isi dari variabel $namaFungsi()
.
Berikut ini kode programnya secara lebih lengkap:
<?php
function validasi(array $listInput)
{
...
foreach ($listInput as $input => $listPeraturan) {
...
foreach ($listPeraturan as $peraturan) {
echo "-> Peraturan <strong>{$peraturan}</strong>: ";
$namaFungsi = 'lolos' . ucfirst($peraturan);
$lolos = $namaFungsi($request[$input]);
echo $lolos ? 'Lolos' : 'Tidak Lolos';
echo "<br>";
}
...
}
}
Jika kita mengeksekusi hasil kodingan kita, kita akan mendapatkan output yang sama persis dengan hasil dari pertemuan validasi form bagian ke-2. Hanya saja, kode programmnya menjadi lebih singkat.
Pesan Error
Selanjutnya kita akan masuk ke dalam inti pembahasan: yaitu membuat dan menampilkan pesan error dari validasi form PHP yang kita bangun.
Agar kode program kita menjadi lebih terstruktur, silakan buat satu file baru dengan nama helper/fungsi-pesan-error.php
. File tersebut nantinya akan kita gunakan untuk men-generate pesan error dari setiap peraturan.
validasi-form/
├── helper/
│ └── fungsi-pesan-error.php
│ └── fungsi-validasi.php
├── form.php
└── proses.php
Buka file helper/fungsi-pesan-error.php
, lalu tulis kode sebagai berikut:
<?php
$listPesanError = [
'required' => function ($field) {
return "Field {$field} harus diisi.";
},
'email' => function ($field) {
return "Field {$field} harus berupa email yang valid.";
},
'numeric' => function ($field) {
return "Field {$field} harus berupa angka numerik.";
},
'url' => function ($field) {
return "Field {$field} harus berupa url yang valid.";
},
'username' => function ($field) {
return "Field {$field} hanya boleh berisi huruf, angka, dan underscore.";
}
];
Penjelasan:
- Kita membuat sebauah variabel bertipe data array asosiatif dengan nama
$listPesanError
. - Masing-masing key dari array
$listPesanError
adalah nama peraturan yang telah kita buat sebelumnya. - Setiap peraturan memiliki nilai berupa fungsi anonim dengan satu buah parameter.
- Setiap fungsi anonim tersebut akan mengembalikan nilai string yang berisi pesan error.
- Pastikan anda telah khatam pembahasan tentang array asosiatif, fungsi anonim, dan fungsi yang mengembalikan nilai.
Memanggil Pesan Error Yang Sesuai
Setelah membuat list fungsi untuk men-generate pesan error. Tahap selanjutnya adalah kita akan memanggil fungsi-fungsi tersebut jika ternyata ada validasi yang tidak lolos.
Langkah yang pertama, pada file helper/fungsi-validasi.php
, hapus semua perintah echo
yang telah kita tulis sebelumhya.
Yang kedua, tambahkan kode berikut di bagian atas file untuk bisa mengakses file helper/fungsi-pesan-error.php
.
<?php
require_once 'fungsi-pesan-error.php';
Setelah itu, pada fungsi validasi()
, setelah pendeklarasian variabel $request
, tambahkan beberapa 2 variabel baru bernama $errors
dan $listPesanError
.
<?php
# variabel yang akan berisi kumpulan pesan error
$errors = [];
# mengakses variabel $listPesanError yang ada di file `fungsi-pesan-error.php`
global $listPesanError;
Penjelasan:
- Variabel
$errors
nantinya akan menjadi array asosiatif yang akan menampung tiap pesan error yang ada. - Perintah
global $listPesanError
berfungsi agar fungsivalidasi()
bisa mengakses variabel$listPesanError
yang berada di luar scope lokal fungsi. - Lebih lengkapnya silakan baca tentang Ruang Lingkup Variabel pada PHP.
Selanjutnya, ubah isi dari foreach()
kedua dari fungsi validasi()
menjadi seperti berikut:
<?php
...
foreach ($listInput as $input => $listPeraturan) {
# perulangan untuk sub array (berisi nama peraturan)
foreach ($listPeraturan as $peraturan) {
$namaFungsi = 'lolos' . ucfirst($peraturan);
$lolos = $namaFungsi(@$request[$input]);
# jika tidak lolos
if (!$lolos) {
if (!is_array(@$errors[$input])) {
$errors += [$input => []];
}
array_push($errors[$input], $listPesanError[$peraturan]($input));
}
}
}
...
Penjelasan:
- Di sini kita melakukan pemeriksaan apakah hasil kembalian dari fungsi
$namaFungsi()
bernilaitrue
ataufalse
- Jika bernilai
false
, kita akan memanggil fungsi pesan error pada variabel$listPesanError
. - Kita melemparkan variabel
$input
ke fungsi$listPesanError[$peraturan]
yang berisi nama field dari form HTML - Hasil kembalian yang kita dapat akan kita kumpulkan pada variabel
$errors
dikelompokkan berdasarkan nama field-nya. - Kode program di atas akan menjadi lebih jelas ketika kita menampilkan variabel
$errors
dengan perintahprint_r
.
Mengembalikan variabel $errors
Langkah yang terakhir yang kita lakukan untuk mengubah fungsi validasi()
adalah: mengembalikan variabel $errors
.
<?php
function validasi(array $listInput)
{
...
return $errors;
}
Memeriksa isi dari variabel $errors
Buka file proses.php
. Ubah cara pemanggilan fungsi validasi()
menjadi seperti berikut:
<?php
$errors = validasi($peraturan);
echo "<pre>";
print_r($errors);
echo "</pre>";
Coba jalankan form, biarkan semua input kosong, lalu klik tombol Submit.
Berikut kira-kira output yang kita dapat:
Coba kembali ke halaman form, isi beberapa input, dan lihat bagaimana output dari variabel $errors
.
Sampai sini inti dari validasi form yang kita buat telah selesai. Tinggal satu hal lagi yaitu: menampilkan pesan error.
Menampilkan Pesan Error Dengan Variabel $_GET (Query String)
Setelah kita berhasil menyimpan pesan error dalam variabel $errors
pada file proses.php
.
Kita akan menampilkan pesan error tersebut di dalam form HTML.
Pertanyaannya adalah: bagaimana caranya mengirimkan variabel yang ada pada file proses.php
, ke dalam file form.php
?
Secara umum, ada dua cara:
- Menggunakan query string
- Menggunakan session PHP (direkomendasikan)
Kita akan coba menggunakan cara yang pertama lebih dahulu.
Redirect ke file form.php dengan membawa pesan error
Buka file proses.php
.
Hapus tag <pre></pre>
yang sebelumnya kita gunakan untuk menampilkan isi dari variabel $errors
.
Lalu ganti dengan blok if
berikut:
<?php
if (count($errors) > 0) {
$old = $_REQUEST;
$queryString = http_build_query([
'errors' => $errors,
'old' => $old
]);
header("Location: form.php?{$queryString}");
die();
}
# di sini kita bisa melakukan proses yang harus dilakukan
# jika tidak terjadi error validasi apa pun.
Penjelasan:
- Pertama kita periksa apakah array
$errors
ada isinya atau tidak. - Jika ada, kita mulai membuat variabel
$queryString
yang berisi variabel$old
dan$errors
. - Variabel
$old
berisi semua nilai input dari request form sebelumnya. Kita akan kirim ulang nilai-nilai tersebut agar user tidak perlu mengisi ulang input yang sebelumnya sudah ia isi. - Fungsi
header("Location: ...")
akan me-redirect request ke halamanform.php
, akan tetapi dengan query string yang telah kita buat. - Fungsi
die()
dipanggil agar script berhenti di sana, dan tidak mengeksekusi kode program di bawah if.
Menangkap dan menampilkan pesan error
Setelah kita berhasil me-redirect dari halaman proses.php
kembali ke halaman form.php
ketika terjadi error. Dan hasil redirect tersebut juga membawa pesan error yang berkaitan, sekarang yang kita harus lakukan adalah menangkap variabel kiriman tersebut dan menampilkannya.
Yang pertama, buka file form.php
.
Kemudian pada bagian paling atas, sebelum tag <!DOCTYPE html>
, tambahkan kode program berikut:
<?php
$old = (object) @$_GET['old'];
$errors = (object) @$_GET['errors'];
?>
Penjelasan::
- Kode program di atas akan membuat 2 buah variabel yaitu variabel
$old
dan$errors
yang diambil dari query string. - Tidak hanya mengambil nilai saja, akan tetapi kode program di atas juga mengkonversi nilai
array
menjadiobject
dari stdClass. - Apakah wajib dikonversi? Tidak. Hanya saja saya lebih suka mengaskses data dari stdClass dibandingkan dari array asosiatif.
Pertahankan value yang lama.
Kita telah menangkan variabel $old
yang berisi nilai inputan terakhir user.
Untuk menampilkannya, kita harus mengubah setiap tag <input>
pada file form.php
, lalu menambahkan atribut value
menjadi seperti berikut:
<input type="text" name="nama" value="<?php echo @$old->nama ?>" placeholder="Masukkan nama">
Lakukan hal di atas untuk semua tag <input>
yang lainnya. Jangan lupa ubah @$old->nama
dengan nilai yang sesuai.
Tampilkan error.
Setelah berhasil mempertahankan nilai form dari request sebelumnya. Kita bisa melakukan hal yang sama untuk menampilkan pesan error. Hanya saja variabel yang kita gunakan adalah variabel $errors
.
Langsung saja, di bawah setiap tag <input>
, tambahkan kode berikut:
<?php
if (@$errors->nama):?>
<div style="color: red"><?php echo $errors->nama[0] ?></div>
<?php
endif; ?>
Ulangi kode program di atas pada setiap <input>
, jangan lupa sesuaikan atribut nama
dengan field yang bersangkutan.
Hasil Akhir
Setelah berhasil tanpa error, kita akan mendapatkan hasil akhir seperti berikut:
Kode Program Lengkap
Kode program lengkap dari pertemuan ini bisa anda akses di repositori github berikut:
https://github.com/jagongoding-com/php-web-dinamis/tree/master/03-validasi-form
Pembahasan Selanjutnya
Insyaallah pada pertemuan selanjutnya kita akan membahas tentang upload file pada PHP.
Ikuti terus serial tutorial PHP web dinamis ini, ya!
Jangan lupa share ke teman-teman kalian! Terima kasih banyak.