Membuat halaman daftar produk dengan beberapa filter sekaligus, misalnya kategori, rentang harga, dan status stok, sering kali berujung pada query yang berantakan atau data yang tidak muncul sesuai harapan. Menampilkan data dari database dengan filter multi-kondisi di PHP membutuhkan pendekatan yang tepat agar query tetap fleksibel dan aman. Berikut langkah praktisnya, dari membangun query dinamis hingga menghindari kesalahan umum.
1. Pahami Konsep Filter Multi-Kondisi
Filter multi-kondisi berarti pengguna dapat memilih beberapa kriteria sekaligus, dan aplikasi harus menampilkan data yang memenuhi semua kriteria tersebut (kondisi AND) atau salah satunya (OR). Tidak semua filter harus diisi. Jika Anda langsung menulis query dengan semua kolom di klausa WHERE, data bisa kosong ketika ada filter yang tidak dipilih. Solusinya adalah membangun query secara dinamis berdasarkan input yang ada.
2. Siapkan Struktur Tabel dan Data Contoh
Sebagai ilustrasi, kita gunakan tabel produk dengan kolom id, nama, kategori, harga, dan stok. Anggap saja Anda sudah memiliki koneksi database menggunakan PDO. Jika belum, pelajari dulu perbandingan PDO dan MySQLi untuk memilih metode yang sesuai.
3. Bangun Query Dinamis dengan Placeholder
Kunci keamanan adalah menggunakan prepared statement. Anda tidak boleh menyisipkan nilai filter langsung ke string query. Mulailah dengan query dasar, lalu tambahkan kondisi hanya jika filter tersedia.
$sql = "SELECT * FROM produk WHERE 1=1";
$params = [];
if (!empty($_GET['kategori'])) {
$sql .= " AND kategori = :kategori";
$params[':kategori'] = $_GET['kategori'];
}
if (!empty($_GET['harga_min'])) {
$sql .= " AND harga >= :harga_min";
$params[':harga_min'] = $_GET['harga_min'];
}
if (!empty($_GET['harga_max'])) {
$sql .= " AND harga 0";
}
Penggunaan WHERE 1=1 memudahkan penambahan kondisi tanpa harus mengecek apakah sudah ada klausa WHERE sebelumnya. Setelah query terbentuk, eksekusi dengan PDO:
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
4. Tangani Filter yang Tidak Diisi
Pastikan setiap filter hanya ditambahkan jika nilainya valid. Gunakan !empty() atau isset() dengan tepat. Untuk filter numerik, validasi dengan is_numeric() agar tidak terjadi error tipe data. Jika filter berupa array (misalnya kategori multiple), Anda perlu membuat placeholder dinamis seperti IN (?, ?, ?) dan menyesuaikan jumlah parameter.
5. Terapkan Pengurutan dan Paginasi
Setelah data terfilter, Anda mungkin perlu mengurutkan berdasarkan harga atau nama. Tambahkan klausa ORDER BY secara dinamis, tetapi pastikan kolom pengurutan berasal dari daftar putih (whitelist) untuk mencegah SQL injection. Untuk data dalam jumlah besar, gabungkan dengan paginasi. Anda bisa mengadaptasi teknik dari panduan pagination PHP tanpa library yang sudah dibahas sebelumnya.
6. Hindari Kesalahan Umum
- Menggabungkan string query dengan input pengguna tanpa sanitasi. Selalu gunakan parameter binding.
- Lupa menambahkan spasi saat menyambung string query, sehingga query menjadi tidak valid.
- Tidak menangani filter kosong yang menyebabkan query mencari nilai kosong dan menghasilkan data kosong.
- Menggunakan operator logika yang salah, misalnya AND padahal seharusnya OR untuk filter yang bersifat pilihan bebas.
7. Uji dengan Berbagai Kombinasi Filter
Setelah kode selesai, uji dengan berbagai skenario: hanya satu filter, dua filter, semua filter, dan tanpa filter sama sekali. Periksa hasil query dengan menampilkan data ke HTML. Jika data tidak muncul, debug query dengan mencetak string SQL dan parameter. Anda juga bisa menggunakan teknik debug query MySQL di PHP untuk melacak masalah.
Ringkasan
Menampilkan data dari database dengan filter multi-kondisi di PHP memerlukan query dinamis yang dibangun secara bertahap, penggunaan prepared statement untuk keamanan, dan validasi input yang ketat. Dengan mengikuti langkah di atas, Anda dapat membuat fitur filter yang fleksibel tanpa mengorbankan performa atau keamanan aplikasi.
Pertanyaan yang Sering Diajukan
Bagaimana jika filter yang dipilih kosong semua?
Jika semua filter kosong, query dasar SELECT * FROM produk WHERE 1=1 akan mengembalikan semua data. Pastikan Anda tetap membatasi jumlah data dengan paginasi agar tidak membebani server.
Apakah bisa menggunakan filter dengan operator OR?
Bisa. Anda perlu mengelompokkan kondisi OR dalam tanda kurung agar tidak mengganggu kondisi AND lainnya. Contoh: AND (kategori = :kat1 OR kategori = :kat2). Gunakan placeholder dinamis untuk jumlah kategori yang bervariasi.
Bagaimana cara menangani input berupa array dari checkbox?
Gunakan implode() untuk membuat placeholder ?,?,? sesuai jumlah elemen array, lalu ikat setiap nilai menggunakan execute() dengan array parameter. Pastikan Anda memvalidasi setiap elemen array sebelum memasukkannya ke query.