Validasi masukan adalah pemeriksaan bentuk dan isi data dari luar program sebelum data dipakai, dan prinsip dasarnya adalah tidak memercayai apa pun yang datang dari luar. Topik ini membahas pola whitelist untuk nilai-nilai tetap, fungsi filter_var untuk format umum, dan ctype_digit untuk pemeriksaan tingkat karakter. Setelah membacanya, setiap masukan dapat dipetakan ke pemeriksaan yang tepat sebelum menyentuh basis data atau keluaran.
Prinsip tidak memercayai masukan#
Data yang masuk melalui $_GET, $_POST, $_COOKIE, header permintaan, dan berkas unggahan semuanya dapat diubah oleh pengirimnya, sehingga tidak ada satu pun yang boleh dibaca lalu dipercaya begitu saja. Validasi di browser dengan atribut required atau type="email" hanyalah kenyamanan bagi pengunjung yang sah, karena permintaan dapat dikirim langsung ke server tanpa browser sama sekali. Pemeriksaan yang menentukan selalu berada di server.
Dua pendekatan validasi berbanding terbalik. Blacklist menyaring nilai-nilai yang dilarang dan selalu tertinggal, karena variasi masukan berbahaya lebih banyak daripada daftar yang mampu disusun. Whitelist bekerja sebaliknya, yaitu menetapkan nilai-nilai yang diizinkan lalu menolak sisanya secara otomatis, sehingga cocok untuk pilihan yang jumlahnya tetap seperti kolom pengurutan atau kategori.
<?php
$_GET['urutan'] = 'nama; DROP TABLE';
$urutanSah = ['nama', 'tanggal', 'judul'];
$urutan = $_GET['urutan'] ?? 'tanggal';
if (!in_array($urutan, $urutanSah, true)) {
$urutan = 'tanggal';
}
echo 'Urutan yang dipakai: ' . $urutan . PHP_EOL;Urutan yang dipakai: tanggalKeluaran menunjukkan bahwa masukan yang memuat perintah asing jatuh ke nilai bawaan tanggal, sehingga nilai mentahnya tidak pernah mencapai query maupun keluaran. Perbandingan in_array dengan argumen ketiga true menggunakan kesetaraan ketat, sehingga nilai yang hanya mirip dengan pilihan sah juga ditolak. Nilai bawaan yang aman dipilih sebagai tempat jatuh bagi setiap masukan yang tidak lolos.
Memvalidasi format dengan filter_var#
Untuk format umum, ekstensi filter menyediakan konstanta pemeriksaan yang siap pakai. filter_var dengan konstanta FILTER_VALIDATE_EMAIL mengembalikan alamat itu sendiri apabila bentuknya sah dan false apabila tidak, sedangkan FILTER_VALIDATE_INT mengembalikan bilangan bulat atau false. Pola kembalian semacam ini membuat pemeriksaan dan konversi tipe terjadi sekaligus.
<?php
var_dump(filter_var('[email protected]', FILTER_VALIDATE_EMAIL));
var_dump(filter_var('budi tidak-valid', FILTER_VALIDATE_EMAIL));
var_dump(filter_var('17', FILTER_VALIDATE_INT));
var_dump(filter_var('tujuh belas', FILTER_VALIDATE_INT));
var_dump(filter_var('2abc', FILTER_VALIDATE_INT));string(19) "[email protected]"
bool(false)
int(17)
bool(false)
bool(false)Keluaran menunjukkan bahwa string '17' dari form menjadi bilangan bulat sungguhan setelah pemeriksaan, sedangkan teks yang tidak memenuhi format ditolak dengan false. Dengan begitu, kode setelahnya selalu bekerja pada tipe yang benar dan tidak perlu mengonversi ulang. Konstanta lain seperti FILTER_VALIDATE_URL dan FILTER_VALIDATE_IP mengikuti pola yang sama, dan daftar lengkapnya ada pada halaman Validate filters di manual PHP.
Penting dicatat bahwa pemeriksaan format ini memastikan bentuk yang sah, bukan isi yang benar. Alamat email yang sah secara bentuk tetap mungkin bukan milik pengirim, sehingga verifikasi kepemilikan seperti tautan konfirmasi tetap diperlukan pada keperluan yang sensitif.
Memeriksa karakter dengan ctype_digit#
Pemeriksaan tingkat karakter berguna ketika aturannya lebih sederhana daripada format penuh. ctype_digit mengembalikan true hanya apabila seluruh karakter string adalah angka, sehingga tanda desimal dan string kosong ikut ditolak. Untuk nomor halaman atau kuantitas, pemeriksaan ini lebih ketat daripada is_numeric yang masih menerima bentuk lain seperti 1e3.
<?php
var_dump(ctype_digit('42'));
var_dump(ctype_digit('42abc'));
var_dump(ctype_digit('4.2'));
var_dump(ctype_digit(''));
$halaman = '3';
if (ctype_digit($halaman) && (int) $halaman > 0) {
echo 'Halaman sah: ' . $halaman . PHP_EOL;
} else {
echo 'Halaman sah: 1' . PHP_EOL;
}bool(true)
bool(false)
bool(false)
bool(false)
Halaman sah: 3Keluaran menegaskan bahwa dari empat bentuk masukan hanya satu yang lolos, sedangkan nomor halaman sah tetap berjalan dengan konversi (int) setelah pemeriksaan. Rangkaian ctype_digit dan pemeriksaan batas membentuk validasi yang ringkas tanpa ekspresi reguler, dan konversi (int) hanya dilakukan pada nilai yang sudah terbukti murni angka.
| Kebutuhan | Fungsi | Kembalian |
|---|---|---|
| Nilai tetap | in_array dengan argumen ketiga true | true atau false |
| Format email | filter_var dengan FILTER_VALIDATE_EMAIL | string atau false |
| Bilangan bulat | filter_var dengan FILTER_VALIDATE_INT | int atau false |
| Angka murni | ctype_digit | true atau false |
Tabel di atas merangkum pemilihan fungsi sesuai kebutuhan, dan seluruhnya mengikuti satu pola yang sama, yaitu memeriksa lebih dahulu sebelum nilai dipakai.
Kesalahan umum#
Empat kesalahan berikut paling sering muncul saat memvalidasi masukan.
- Validasi hanya berada di browser. Permintaan yang dikirim langsung ke server melewati seluruh pemeriksaan browser, sehingga data tidak sah tetap sampai ke PHP. Perbaikannya adalah mengulang seluruh pemeriksaan di server sebelum data dipakai.
- Penyaringan memakai blacklist kata terlarang. Daftar terlarang selalu tertinggal terhadap variasi baru dan mudah dilewati dengan pengodean yang berbeda. Perbaikannya adalah whitelist nilai yang sah beserta nilai bawaan yang aman.
- Angka dipakai langsung dari
$_GETtanpa pemeriksaan. Nilainya berupa string dan dapat berisi apa pun, sehingga query atau perhitungan menerima data rusak. Perbaikannya adalahFILTER_VALIDATE_INTatauctype_digitsebelum konversi(int). - Alamat email diperiksa dengan ekspresi reguler buatan sendiri. Pola yang tidak lengkap menolak alamat yang sah atau menerima bentuk yang tidak wajar. Perbaikannya adalah
FILTER_VALIDATE_EMAILyang aturannya dijaga manual PHP.
Ringkasan#
- Setiap data dari luar program dianggap tidak terpercaya, dan pemeriksaan yang menentukan berjalan di server.
- Whitelist menetapkan nilai yang diizinkan lalu menolak sisanya, dan paling tepat untuk pilihan yang jumlahnya tetap.
filter_varmemeriksa format umum sekaligus mengonversi tipe, sedangkanctype_digitmemeriksa angka murni pada tingkat karakter.- Masukan yang gagal validasi jatuh ke nilai bawaan yang aman, bukan dipakai dalam bentuk mentahnya.
Referensi#
- filter_var — PHP Manual — Dokumentasi penyaringan data dengan filter tertentu.
- Validate filters — PHP Manual — Daftar lengkap konstanta filter validasi beserta aturannya.
- ctype_digit — PHP Manual — Dokumentasi pemeriksaan karakter angka pada string.
- Input Validation Cheat Sheet — OWASP — Panduan prinsip validasi masukan dan pendekatan whitelist.