Form Handling dengan PHP

Salah satu fungsi utama PHP adalah menerima data dari form HTML. Ketika pengguna mengisi form dan klik submit, data dikirim ke server dan PHP yang memprosesnya.

Method GET vs POST

Ada dua cara form mengirim data:

MethodCiriKapan Dipakai
GETData muncul di URLPencarian, filter, halaman yang bisa di-bookmark
POSTData tersembunyiLogin, registrasi, data sensitif

Contoh GET

<!-- form-cari.html -->
<form action="cari.php" method="GET">
    <input type="text" name="kata" placeholder="Cari...">
    <button type="submit">Cari</button>
</form>

URL setelah submit: cari.php?kata=php

<!-- cari.php -->
<?php
$kata = $_GET['kata'] ?? '';   // Ambil data dari URL
echo "Anda mencari: $kata";
?>

Contoh POST

<!-- form-login.html -->
<form action="login.php" method="POST">
    <input type="text" name="username" placeholder="Username">
    <input type="password" name="password" placeholder="Password">
    <button type="submit">Login</button>
</form>
<!-- login.php -->
<?php
$username = $_POST['username'] ?? '';
$password = $_POST['password'] ?? '';
echo "Username: $username";
// Password TIDAK ditampilkan di URL
?>

Variabel Superglobal

PHP menyediakan variabel khusus untuk menerima data:

VariabelFungsi
$_GETData dari form method GET (atau URL)
$_POSTData dari form method POST
$_REQUESTGabungan GET + POST
$_SERVERInformasi server & request
$_SESSIONData session (dibahas di bab session)
$_COOKIEData cookie
$_FILESFile yang diupload

Validasi dan Sanitasi

Jangan Pernah Percaya Data dari User!

Data dari form bisa dimanipulasi oleh pengguna. Selalu validasi dan sanitasi sebelum digunakan.

<?php
// Menerima data
$nama = $_POST['nama'] ?? '';
$email = $_POST['email'] ?? '';
$umur = $_POST['umur'] ?? '';

// Sanitasi — bersihkan data
$nama = htmlspecialchars(trim($nama));       // Hapus spasi & tag HTML
$email = filter_var(trim($email), FILTER_SANITIZE_EMAIL);
$umur = (int) $umur;                         // Paksa jadi integer

// Validasi — cek apakah data valid
$errors = [];

if (empty($nama)) {
    $errors[] = "Nama wajib diisi";
} elseif (strlen($nama) < 3) {
    $errors[] = "Nama minimal 3 karakter";
}

if (empty($email)) {
    $errors[] = "Email wajib diisi";
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
    $errors[] = "Format email tidak valid";
}

if ($umur < 1 || $umur > 150) {
    $errors[] = "Umur tidak valid";
}

// Cek hasil validasi
if (empty($errors)) {
    echo "Data valid! Nama: $nama, Email: $email, Umur: $umur";
} else {
    foreach ($errors as $error) {
        echo "<p style='color:red'>⚠️ $error</p>";
    }
}
?>

Fungsi Keamanan Penting

FungsiKegunaan
htmlspecialchars()Mencegah XSS — mengubah <script> menjadi teks biasa
trim()Menghapus spasi di awal dan akhir string
filter_var()Validasi & sanitasi (email, URL, angka, dll)
(int) / intval()Paksa konversi ke integer
XSS (Cross-Site Scripting)

Tanpa htmlspecialchars(), pengguna bisa memasukkan kode JavaScript berbahaya lewat form:

// ❌ BAHAYA — tanpa sanitasi
echo $_POST['nama'];  // Pengguna bisa input: <script>alert('hacked')</script>

// ✅ AMAN — dengan sanitasi
echo htmlspecialchars($_POST['nama']);  // Output: &lt;script&gt;alert('hacked')&lt;/script&gt;

Form Lengkap: Satu File PHP

Cara paling umum adalah menggunakan satu file PHP untuk menampilkan form DAN memprosesnya:

<?php
// proses.php — Form dan pemrosesan dalam satu file
$nama = '';
$email = '';
$pesan = '';
$errors = [];
$sukses = false;

// Cek apakah form di-submit
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // Ambil dan sanitasi data
    $nama = htmlspecialchars(trim($_POST['nama'] ?? ''));
    $email = filter_var(trim($_POST['email'] ?? ''), FILTER_SANITIZE_EMAIL);
    $pesan = htmlspecialchars(trim($_POST['pesan'] ?? ''));

    // Validasi
    if (empty($nama)) $errors[] = "Nama wajib diisi";
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) $errors[] = "Email tidak valid";
    if (empty($pesan)) $errors[] = "Pesan wajib diisi";

    // Jika valid
    if (empty($errors)) {
        $sukses = true;
        // Di sini nanti kita simpan ke database
    }
}
?>

<!DOCTYPE html>
<html lang="id">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Kontak Kami</title>
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body { font-family: 'Segoe UI', sans-serif; background: #f0f2f5; padding: 40px 20px; }
        .container { max-width: 500px; margin: 0 auto; background: white;
                     padding: 30px; border-radius: 12px;
                     box-shadow: 0 4px 15px rgba(0,0,0,0.1); }
        h1 { text-align: center; color: #667eea; margin-bottom: 20px; }
        .form-group { margin-bottom: 15px; }
        label { display: block; margin-bottom: 5px; font-weight: 600; color: #444; }
        input, textarea { width: 100%; padding: 10px 14px; border: 2px solid #ddd;
                         border-radius: 8px; font-size: 15px; font-family: inherit; }
        input:focus, textarea:focus { outline: none; border-color: #667eea; }
        button { width: 100%; padding: 12px; background: #667eea; color: white;
                border: none; border-radius: 8px; font-size: 16px; cursor: pointer; }
        button:hover { background: #5a6fd6; }
        .alert-error { background: #fde8e8; border: 1px solid #dc3545; color: #dc3545;
                      padding: 12px; border-radius: 8px; margin-bottom: 15px; }
        .alert-success { background: #e8f5e9; border: 1px solid #28a745; color: #28a745;
                        padding: 12px; border-radius: 8px; margin-bottom: 15px; text-align: center; }
    </style>
</head>
<body>
    <div class="container">
        <h1>📬 Kontak Kami</h1>

        <?php if ($sukses): ?>
            <div class="alert-success">
                <p>✅ Terima kasih, <strong><?= $nama ?></strong>!</p>
                <p>Pesan kamu sudah kami terima.</p>
            </div>
        <?php endif; ?>

        <?php if (!empty($errors)): ?>
            <div class="alert-error">
                <?php foreach ($errors as $error): ?>
                    <p>⚠️ <?= $error ?></p>
                <?php endforeach; ?>
            </div>
        <?php endif; ?>

        <?php if (!$sukses): ?>
        <form method="POST">
            <div class="form-group">
                <label for="nama">Nama</label>
                <input type="text" id="nama" name="nama" value="<?= $nama ?>" required>
            </div>

            <div class="form-group">
                <label for="email">Email</label>
                <input type="email" id="email" name="email" value="<?= $email ?>" required>
            </div>

            <div class="form-group">
                <label for="pesan">Pesan</label>
                <textarea id="pesan" name="pesan" rows="5" required><?= $pesan ?></textarea>
            </div>

            <button type="submit">Kirim Pesan</button>
        </form>
        <?php endif; ?>
    </div>
</body>
</html>
Sticky Form

Perhatikan value="<?= $nama ?>" pada input. Ini disebut sticky form — kalau ada error, data yang sudah diketik tidak hilang. Pengguna tidak perlu mengisi ulang dari awal!

Selanjutnya

Sekarang PHP sudah bisa menerima data dari form. Tapi data menghilang setelah halaman di-refresh. Kita perlu database untuk menyimpan data secara permanen. Mari belajar Koneksi Database →.

❓ Error Umum Pemula

:::warning Sering Terjadi!

  1. Undefined array key "nama": Error ini muncul karena kamu mencoba membaca $_POST['nama'] padahal form belum disubmit oleh user (halaman baru diload pertama kali). Solusi: Selalu gunakan pengecekan if ($_SERVER['REQUEST_METHOD'] == 'POST') sebelum membaca $_POST.
  2. Lupa Atribut name di HTML: Misal kamu menulis <input type="text" id="email"> (kurang atribut name="email"). Akibatnya: Data tidak akan pernah terkirim ke PHP! PHP tidak membaca id, PHP hanya membaca atribut name.
  3. Tertukar GET dan POST: Form di HTML menggunakan method="POST", tapi di PHP kamu mengambilnya menggunakan $_GET['nama']. Data akan selalu kosong! :::