Form Handling — PHP

PHP bisa memproses data dari form HTML menggunakan superglobal $_GET dan $_POST. Form HTML → PHP: Kirim Memproses di PHP: if ($_SERVER["REQUEST_METHOD"] ===…

Form adalah cara browser mengirim isian pengunjung ke server, dan PHP menerimanya sebagai array. Bayangin kertas pesanan di Warung Bu Tini. Pembeli mengisi menu, jumlah, dan catatan, lalu kertasnya diantar ke dapur. Kertas bisa diantar terbuka, isinya kebaca siapa saja yang lewat (itu GET, isinya ditempel di URL), atau di dalam amplop (itu POST, isinya di badan request). Di dapur, Bu Tini gak langsung percaya isinya: menunya dicek ada atau gak, jumlahnya masuk akal atau gak. PHP juga harus begitu.

🧪 Tebakan cepat: form pesanan punya checkbox "Pedas". Pembeli gak mencentangnya lalu menekan Pesan. Di PHP, $_POST["pedas"] isinya apa: "", false, atau ada yang lain? Tebak dulu, jawabannya ada di bagian "Field yang gak terkirim".

Form mengirim, PHP menerima

<form method="post" action="pesan.php">
  <select name="menu">
    <option>Nasi Goreng</option><option>Mie Ayam</option><option>Es Teh</option>
  </select>
  <input name="jumlah" value="1">
  <input name="catatan">
  <label><input type="checkbox" name="pedas" value="ya"> Pedas</label>
  <button>Pesan</button>
</form>

Pembeli memilih Nasi Goreng, mengetik jumlah 2, mencentang Pedas, lalu menekan Pesan. Browser mengirim request ini ke pesan.php:

POST /pesan.php HTTP/1.1
Content-Type: application/x-www-form-urlencoded

menu=Nasi+Goreng&jumlah=2&catatan=&pedas=ya

Di pesan.php, isian itu sudah jadi array $_POST. print_r($_POST); menulis:

Array
(
    [menu] => Nasi Goreng
    [jumlah] => 2
    [catatan] => 
    [pedas] => ya
)
GET POST
Isian dikirim lewat URL (query string, bagian setelah ?) badan request
Dibaca PHP dari $_GET $_POST
Pas untuk membaca: cari menu, halaman 2 mengubah data: pesan, daftar, login
Kalau di-refresh aman, cuma membaca lagi browser bertanya mau kirim ulang atau gak

Field yang gak terkirim: ?? dan isset

Checkbox yang gak dicentang gak dikirim sama sekali. Gak ada pedas= di request, jadi key pedas gak ada di $_POST. Membacanya langsung:

$pedas = $_POST["pedas"];
Warning: Undefined array key "pedas" in /var/www/warung/pesan.php on line 17

Isinya bukan "" atau false: key-nya gak ada, PHP memberi Warning dan $pedas jadi null (baris 17 adalah baris itu di pesan.php lengkap yang ada di Lab). Itu jawaban tebakannya. Input teks yang dikosongkan beda: dia tetap dikirim (catatan=), jadi $_POST["catatan"] ada dan isinya "".

Cara membaca yang aman:

if ($_SERVER["REQUEST_METHOD"] === "POST") {
    $menu = $_POST["menu"] ?? "";
    $catatan = $_POST["catatan"] ?? "";
    $pedas = isset($_POST["pedas"]);
}

Validasi: periksa semua field sebelum dipakai

Field wajib dicek satu per satu dengan perulangan, bukan ditulis berulang:

$_POST = ["nama" => "Budi", "email" => "", "pesan" => "Halo!"];

$valid = true;
foreach (["nama", "email", "pesan"] as $field) {
    if (empty($_POST[$field])) {
        echo "Error: $field wajib diisi\n";
        $valid = false;
    }
}

if ($valid) {
    echo "Terima kasih, " . $_POST["nama"] . "! Pesan diterima.";
}
// Error: email wajib diisi

Untuk isi yang harus berupa angka atau email, pakai filter bawaan PHP:

$jumlah = filter_input(INPUT_POST, "jumlah", FILTER_VALIDATE_INT, [
    "options" => ["min_range" => 1, "max_range" => 20],
]);
Isian jumlah Hasil
2 int(2)
3 (dengan spasi) int(3)
dua, 2.5, 25, 0 false
field gak dikirim null

Output: htmlspecialchars setiap kali menulis isian

Pembeli menulis catatan <b>pedas</b>. Kalau di-echo apa adanya, browser membacanya sebagai tag, dan catatan berisi <script> ikut dijalankan di browser orang lain. Itu XSS (cross-site scripting).

echo "<p>Catatan: " . htmlspecialchars($catatan) . "</p>";
// <p>Catatan: &lt;b&gt;pedas&lt;/b&gt;</p>

💡 POST/Redirect/GET

Setelah pesanan disimpan, kalau halaman POST langsung menulis "Pesanan masuk", tombol refresh mengirim POST yang sama lagi, dan pesanannya jadi dobel. Polanya: simpan, lalu suruh browser pindah dengan GET.

$id = simpanPesanan($menu, $jumlah, $catatan, $pedas);
header("Location: pesan.php?id=$id", true, 303);
exit;

Form POST yang mengubah data juga butuh CSRF token: nilai acak di input tersembunyi yang dicocokkan dengan yang disimpan di session. Tujuannya mencegah CSRF, yaitu situs lain diam-diam mengirim form ke warungmu atas nama pembeli yang sedang login. Caranya ada di lesson CSRF (Cross-Site Request Forgery) di track Security.

⚠️ Jebakan yang sering ketemu

TL;DR: Form mengirim isiannya ke PHP: method="get" lewat URL ke $_GET, method="post" lewat badan request ke $_POST. Key-nya dari atribut name, value-nya selalu string. Checkbox yang gak dicentang gak dikirim, jadi membacanya langsung memberi Warning: Undefined array key; baca dengan isset() atau ??, dan cek $_SERVER["REQUEST_METHOD"] === "POST" dulu. Validasi semua field di server (foreach + empty, filter_input/filter_var dengan FILTER_VALIDATE_INT), lalu tulis isian ke halaman lewat htmlspecialchars() supaya gak jadi XSS. Setelah POST berhasil, redirect dengan header("Location: ...", true, 303); exit; supaya refresh gak mengirim ulang, dan form POST yang mengubah data butuh CSRF token.

Yang akan kamu pelajari