Cara Membuat Kolom Pencarian PHP dan Filter Data

Kamu punya tabel daftar barang, lalu ingin menambahkan kotak pencarian di atasnya. Setelah form dikirim, halamannya kosong atau malah menampilkan seluruh data tanpa filter. Penyebabnya hampir selalu satu: nilai input tidak terbaca atau query tidak menyertakan klausa WHERE. Panduan ini membahas cara membuat kolom pencarian PHP yang menampilkan hasil sesuai kata kunci, aman dari manipulasi query, dan tetap berjalan saat kotak pencarian dikosongkan.

Menyiapkan form pencarian dengan metode GET

Pencarian adalah operasi baca. Pakai metode GET supaya kata kunci muncul di URL dan hasilnya bisa dibagikan atau di-bookmark. Form dengan metode POST akan membuat halaman hasil hilang saat di-refresh.

<form action="daftar.php" method="get">
  <input type="text" name="q" placeholder="Cari nama barang"
         value="<?= htmlspecialchars($_GET['q'] ?? '') ?>">
  <button type="submit">Cari</button>
</form>

Fungsi htmlspecialchars() dipakai saat menulis nilai kembali ke atribut value. Tanpa itu, karakter seperti tanda kutip ganda bisa memutus atribut dan merusak tampilan form. Operator ?? mencegah peringatan undefined index saat halaman pertama kali dibuka.

Membaca kata kunci dan menyiapkan query

Langkah berikutnya ada di sisi server. Ambil nilai q, potong spasi di awal dan akhir dengan trim(), lalu cek apakah isinya kosong. Kalau kosong, jalankan query tanpa filter. Kalau ada isinya, tambahkan klausa WHERE dengan placeholder.

$q = trim($_GET['q'] ?? '');

if ($q === '') {
    $stmt = $pdo->query("SELECT id, nama, harga FROM barang ORDER BY nama");
} else {
    $stmt = $pdo->prepare(
        "SELECT id, nama, harga FROM barang WHERE nama LIKE ? ORDER BY nama"
    );
    $stmt->execute(['%' . $q . '%']);
}

$hasil = $stmt->fetchAll(PDO::FETCH_ASSOC);

Tanda % di kiri dan kanan kata kunci membuat pencarian bersifat contains: kata kunci boleh muncul di tengah nama. Nilai $q tidak pernah disisipkan langsung ke string SQL, hanya dikirim lewat execute(). Pola ini sama dengan yang dibahas di cara mencegah SQL injection di PHP dengan prepared statement, dan sebaiknya kamu terapkan konsisten di semua query yang menerima input pengguna.

Menangani beberapa kolom sekaligus

Kotak pencarian sering diminta mencari di beberapa kolom, misalnya nama dan kode barang. Tambahkan kondisi OR di dalam tanda kurung supaya tidak bercampur dengan filter lain.

$stmt = $pdo->prepare(
    "SELECT id, nama, kode FROM barang
     WHERE (nama LIKE ? OR kode LIKE ?)
     ORDER BY nama"
);
$stmt->execute(["%$q%", "%$q%"]);

Jumlah placeholder harus sama dengan jumlah nilai di array execute(). Kalau kamu menambah kolom ketiga, tambahkan pula satu ? dan satu nilai. Kelalaian di sini memunculkan error seperti Invalid parameter number.

Menggabungkan pencarian dengan filter lain

Di halaman daftar yang punya filter kategori dan status, query bisa cepat berantakan. Susun kondisi secara bertahap dalam array, lalu gabungkan dengan AND. Cara ini lebih mudah dibaca daripada menumpuk if di dalam string SQL.

$kondisi = [];
$nilai = [];

if ($q !== '') {
    $kondisi[] = "nama LIKE ?";
    $nilai[] = "%$q%";
}

$kategori = $_GET['kategori'] ?? '';
if ($kategori !== '') {
    $kondisi[] = "kategori = ?";
    $nilai[] = $kategori;
}

$sql = "SELECT id, nama FROM barang";
if ($kondisi) {
    $sql .= " WHERE " . implode(' AND ', $kondisi);
}
$sql .= " ORDER BY nama";

$stmt = $pdo->prepare($sql);
$stmt->execute($nilai);

Urutan nilai di array $nilai harus mengikuti urutan kemunculan placeholder di $sql. Karena keduanya dibangun bersamaan, urutannya otomatis sinkron.

Menampilkan hasil dan keadaan kosong

Hasil pencarian perlu memberi tahu pengguna apa yang terjadi. Ada tiga keadaan yang harus ditangani: ada hasil, tidak ada hasil, dan kata kunci belum diisi.

  • Ada hasil: tampilkan jumlah baris dan daftar datanya.
  • Tidak ada hasil: tulis pesan yang menyebut kata kunci yang dicari.
  • Kata kunci kosong: tampilkan semua data dengan pesan bahwa pencarian belum dijalankan.
if ($q !== '' && !$hasil) {
    echo "Tidak ada data yang cocok dengan "" . htmlspecialchars($q) . "".";
}

foreach ($hasil as $row) {
    echo "<li>" . htmlspecialchars($row['nama']) . "</li>";
}

Setiap data yang berasal dari database tetap harus melewati htmlspecialchars() saat dicetak ke HTML. Ini melindungi tampilan dari karakter yang tidak diharapkan di dalam nama barang. Pembahasan lengkap soal perulangan dan escape ada di cara menampilkan data dari database ke HTML dengan PHP.

Menjaga hasil pencarian tetap bisa dipaginasi

Kalau daftar datanya panjang, pencarian harus berjalan bersama pagination. Simpan kata kunci di setiap tautan halaman, kalau tidak, halaman kedua akan menampilkan semua data tanpa filter.

$link = "daftar.php?q=" . urlencode($q) . "&page=" . $halaman;

Gunakan urlencode() khusus untuk parameter URL, bukan htmlspecialchars(). Keduanya punya konteks berbeda: yang satu untuk URL, yang satu untuk HTML. Contoh penerapan pagination yang menyertakan kata kunci dibahas di cara membuat pagination PHP tanpa library tambahan.

Kesalahan yang paling sering muncul

Beberapa masalah berulang di kode pencarian yang ditanyakan di forum:

  1. Memakai $_POST padahal form dikirim dengan metode GET, sehingga $_POST['q'] selalu kosong.
  2. Menulis LIKE '%$q%' langsung ke query. Selain rawan injeksi, tanda kutip di kata kunci akan memicu error sintaks SQL.
  3. Lupa trim(), sehingga spasi saja dianggap kata kunci dan menghasilkan pencarian yang tidak berguna.
  4. Menghapus parameter q dari tautan pagination, membuat filter hilang saat pindah halaman.
  5. Mencetak $q tanpa escape, sehingga tag HTML di kotak pencarian ikut dieksekusi browser.

Menangani lima hal ini biasanya cukup membuat kolom pencarian berjalan stabil di data berukuran kecil sampai menengah.

Ringkasan

Kolom pencarian PHP terdiri dari tiga bagian: form GET yang menulis kembali nilai input dengan aman, query dengan placeholder yang menyusun kondisi WHERE secara bertahap, dan tampilan yang menangani hasil kosong maupun kata kunci kosong. Selama nilai pengguna tidak pernah masuk langsung ke string SQL dan setiap tautan membawa parameter pencarian, fitur ini bisa dipakai tanpa mengubah struktur kode lain di halamanmu.

Pertanyaan yang Sering Diajukan

Kenapa hasil pencarian hanya muncul saat menekan Enter?

Pastikan tombol submit berada di dalam elemen <form> dan tag form ditutup dengan benar. Kalau tombol ada di luar form, browser tidak mengirim apa pun. Cek juga atribut action apakah menunjuk ke file yang memproses pencarian.

Apakah LIKE bisa dipakai untuk data angka?

Bisa, tetapi hasilnya pencocokan teks, bukan angka. Mencari 10 pada kolom harga akan cocok dengan 100 dan 210. Untuk angka, gunakan perbandingan seperti =, >, atau BETWEEN dengan placeholder juga.

Bagaimana kalau data yang dicari sangat banyak?

Pencarian dengan wildcard di kedua sisi membuat indeks kolom tidak terpakai, sehingga query melambat saat data bertambah besar. Untuk kebutuhan seperti itu, pertimbangkan fitur pencarian penuh dari database yang kamu pakai atau batasi hasil dengan pagination.