Sebagai seorang developer web, menampilkan data dari database adalah salah satu tugas fundamental yang akan sering Anda lakukan. Baik itu daftar produk e-commerce, postingan blog, atau profil pengguna, data dinamis adalah inti dari hampir setiap aplikasi web modern. Namun, bagi sebagian pemula, proses koneksi dan penarikan data ini terkadang terasa membingungkan.
Dalam panduan ini, kita akan membahas langkah demi langkah cara menampilkan data dari database menggunakan PHP. Kita akan fokus pada database MySQL/MariaDB, yang merupakan kombinasi paling umum dengan PHP, dan menggunakan ekstensi mysqli dalam gaya object-oriented yang lebih modern dan direkomendasikan. Tidak hanya itu, kita juga akan menyentuh aspek keamanan yang krusial, memastikan data Anda ditampilkan dengan cara yang benar dan aman.
Mari kita mulai perjalanan kita untuk membuat aplikasi web yang lebih dinamis!
Persiapan Awal: Database dan Contoh Data
Sebelum kita bisa menampilkan data, tentu saja kita memerlukan data itu sendiri. Di sini, kita akan menyiapkan sebuah database sederhana dan sebuah tabel dengan beberapa contoh data.
1. Membuat Database
Pertama, pastikan Anda sudah memiliki server database (misalnya MySQL atau MariaDB) yang berjalan. Anda bisa menggunakan XAMPP, Laragon, atau LAMP stack. Kita akan membuat database baru bernama db_blog.
Anda bisa melakukannya melalui phpMyAdmin, Adminer, atau via terminal:
- Buka terminal/CMD Anda.
- Login ke MySQL:
mysql -u root -p(masukkan password jika ada). - Buat database:
CREATE DATABASE db_blog; - Pilih database:
USE db_blog;
2. Membuat Tabel Contoh
Selanjutnya, kita akan membuat sebuah tabel bernama artikel di dalam database db_blog untuk menyimpan data artikel blog.
Jalankan perintah SQL berikut:
CREATE TABLE artikel ( id INT(11) AUTO_INCREMENT PRIMARY KEY, judul VARCHAR(255) NOT NULL, isi TEXT NOT NULL, tanggal_publish DATETIME DEFAULT CURRENT_TIMESTAMP );
3. Memasukkan Contoh Data
Agar ada data yang bisa ditampilkan, mari kita masukkan beberapa contoh artikel:
INSERT INTO artikel (judul, isi) VALUES ('Belajar PHP Dasar', 'Ini adalah artikel tentang dasar-dasar pemrograman PHP untuk pemula.');
INSERT INTO artikel (judul, isi) VALUES ('Mengenal SQL Injection', 'Artikel ini membahas apa itu SQL Injection dan cara mencegahnya.');
INSERT INTO artikel (judul, isi) VALUES ('Optimasi Database MySQL', 'Tips dan trik untuk mengoptimasi kinerja database MySQL Anda.');
Setelah langkah-langkah ini, kita siap untuk mulai menulis kode PHP.
Koneksi ke Database Menggunakan PHP (mysqli)
Langkah pertama dalam setiap interaksi database adalah membuat koneksi. Kita akan menggunakan ekstensi mysqli yang merupakan antarmuka untuk MySQL/MariaDB. Untuk project modern, saya selalu merekomendasikan gaya object-oriented karena lebih bersih dan terstruktur.
Buat sebuah file bernama koneksi.php:
<?php
$host = "localhost";
$user = "root";
$pass = ""; // Kosongkan jika tidak ada password
$db = "db_blog";
// Buat objek koneksi
$koneksi = new mysqli($host, $user, $pass, $db);
// Cek koneksi
if ($koneksi->connect_error) {
die("Koneksi gagal: " . $koneksi->connect_error);
}
// echo "Koneksi berhasil!"; // Bisa dihapus setelah dipastikan koneksi berhasil
?>
Penjelasan:
$host: Biasanyalocalhostjika database berjalan di mesin yang sama.$user: Nama pengguna database, default-nyaroot.$pass: Password database, default-nya kosong jika menggunakan XAMPP/Laragon.$db: Nama database yang ingin kita sambungkan (db_blog).new mysqli(...): Membuat instance objekmysqliyang akan menangani koneksi.$koneksi->connect_error: Properti ini akan berisi pesan error jika koneksi gagal.die(...): Menghentikan eksekusi script dan menampilkan pesan error. Ini penting untuk debugging.
Selalu ingat untuk menyertakan file koneksi.php ini di awal setiap script PHP yang membutuhkan akses database.
Menampilkan Data Sederhana (SELECT *)
Setelah koneksi berhasil dibuat, kita bisa mulai mengambil data. Kita akan menampilkan semua data dari tabel artikel.
Buat file baru, misalnya index.php:
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Daftar Artikel</title>
<style>
body { font-family: sans-serif; margin: 20px; }
table { width: 100%; border-collapse: collapse; margin-top: 20px; }
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
th { background-color: #f2f2f2; }
</style>
</head>
<body>
<h1>Daftar Artikel</h1>
<table>
<thead>
<tr>
<th>ID</th>
<th>Judul</th>
<th>Isi</th>
<th>Tanggal Publish</th>
</tr>
</thead>
<tbody>
<?php
include 'koneksi.php'; // Sertakan file koneksi
// Query untuk mengambil semua data dari tabel artikel
$sql = "SELECT id, judul, isi, tanggal_publish FROM artikel ORDER BY tanggal_publish DESC";
$result = $koneksi->query($sql); // Eksekusi query
// Cek apakah ada data yang ditemukan
if ($result->num_rows > 0) {
// Loop melalui setiap baris data dan tampilkan
while($row = $result->fetch_assoc()) {
echo "<tr>";
echo "<td>" . $row["id"] . "</td>";
echo "<td>" . htmlspecialchars($row["judul"]) . "</td>";
echo "<td>" . htmlspecialchars(substr($row["isi"], 0, 100)) . "...</td>"; // Tampilkan 100 karakter pertama
echo "<td>" . $row["tanggal_publish"] . "</td>";
echo "</tr>";
}
} else {
echo "<tr><td colspan='4'>Tidak ada artikel yang ditemukan.</td></tr>";
}
// Tutup koneksi database
$koneksi->close();
?>
</tbody>
</table>
</body>
</html>
Penjelasan:
include 'koneksi.php';: Mengimpor file koneksi yang sudah kita buat.$sql = "SELECT ... FROM artikel ORDER BY tanggal_publish DESC";: Ini adalah query SQL untuk mengambil kolomid,judul,isi, dantanggal_publishdari tabelartikel, diurutkan dari yang terbaru.$result = $koneksi->query($sql);: Mengeksekusi query SQL. Objek$resultakan berisi hasil dari query.if ($result->num_rows > 0): Mengecek apakah ada baris data yang dikembalikan oleh query. Jika lebih dari 0, berarti ada data.while($row = $result->fetch_assoc()): Ini adalah inti dari menampilkan data. Fungsifetch_assoc()mengambil satu baris data sebagai array asosiatif (nama kolom sebagai kunci array) dan menggeser pointer ke baris berikutnya. Loop ini akan terus berjalan sampai tidak ada baris lagi.$row["id"],$row["judul"], dst.: Mengakses nilai dari setiap kolom.htmlspecialchars(): Ini adalah fungsi penting untuk keamanan! Selalu gunakan ini saat menampilkan data yang berasal dari database atau input user ke halaman HTML. Ini mencegah serangan Cross-Site Scripting (XSS).substr($row["isi"], 0, 100): Untuk kolomisiyang panjang, kita bisa memotongnya agar tidak terlalu memenuhi tabel.$koneksi->close();: Sangat penting untuk menutup koneksi database setelah selesai menggunakannya untuk membebaskan sumber daya server.
Menampilkan Data dengan Kondisi (WHERE Clause)
Seringkali, Anda tidak ingin menampilkan semua data, melainkan data tertentu berdasarkan kriteria. Di sinilah klausa WHERE berperan.
Misalnya, Anda ingin mencari artikel dengan ID tertentu, atau judul yang mengandung kata kunci tertentu. Ini biasanya dilakukan dengan menerima input dari pengguna (misalnya dari URL melalui parameter GET).
Mari kita buat contoh di mana kita hanya menampilkan satu artikel berdasarkan ID yang diberikan di URL. Ubah file index.php atau buat file baru seperti detail_artikel.php:
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Detail Artikel</title>
<style>
body { font-family: sans-serif; margin: 20px; line-height: 1.6; }
.article-container { max-width: 800px; margin: auto; padding: 20px; border: 1px solid #eee; border-radius: 8px; }
h1 { color: #333; }
p.meta { font-size: 0.9em; color: #777; }
</style>
</head>
<body>
<div class="article-container">
<?php
include 'koneksi.php';
$id_artikel = isset($_GET['id']) ? (int)$_GET['id'] : 0; // Ambil ID dari URL, pastikan integer
if ($id_artikel > 0) {
$sql = "SELECT judul, isi, tanggal_publish FROM artikel WHERE id = $id_artikel";
$result = $koneksi->query($sql);
if ($result->num_rows > 0) {
$row = $result->fetch_assoc();
echo "<h1>" . htmlspecialchars($row["judul"]) . "</h1>";
echo "<p class='meta'>Dipublikasikan pada: " . $row["tanggal_publish"] . "</p>";
echo "<p>" . nl2br(htmlspecialchars($row["isi"])) . "</p>"; // nl2br untuk baris baru dari TEXTAREA
} else {
echo "<p>Artikel tidak ditemukan.</p>";
}
} else {
echo "<p>ID artikel tidak valid.</p>";
}
$koneksi->close();
?>
<p><a href="index.php">Kembali ke Daftar Artikel</a></p>
</div>
</body>
</html>
Untuk mengaksesnya, Anda bisa buka detail_artikel.php?id=1 (ganti 1 dengan ID artikel yang ada di database Anda).
Menggunakan Prepared Statements untuk Keamanan (PENTING!)
Pada contoh di atas, kita langsung menyisipkan variabel $id_artikel ke dalam query SQL. Cara ini sangat berbahaya dan rentan terhadap serangan SQL Injection, terutama jika nilai $id_artikel berasal dari input pengguna yang tidak disaring dengan baik.
SQL Injection adalah teknik serangan di mana penyerang menyisipkan kode SQL berbahaya ke dalam input aplikasi untuk memanipulasi atau mendapatkan akses tidak sah ke database. Contoh: Jika input adalah 1 OR 1=1, query akan menjadi SELECT ... WHERE id = 1 OR 1=1 yang akan mengembalikan semua data.
Solusi terbaik untuk mencegah SQL Injection adalah dengan menggunakan Prepared Statements. Ini memisahkan query SQL dari data yang akan disisipkan, sehingga database tahu mana bagian query dan mana bagian data.
Mari kita refactor kode detail_artikel.php untuk menggunakan prepared statements:
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Detail Artikel Aman</title>
<style>
body { font-family: sans-serif; margin: 20px; line-height: 1.6; }
.article-container { max-width: 800px; margin: auto; padding: 20px; border: 1px solid #eee; border-radius: 8px; }
h1 { color: #333; }
p.meta { font-size: 0.9em; color: #777; }
</style>
</head>
<body>
<div class="article-container">
<?php
include 'koneksi.php';
$id_artikel = isset($_GET['id']) ? (int)$_GET['id'] : 0;
if ($id_artikel > 0) {
// 1. Siapkan query dengan placeholder (?)
$stmt = $koneksi->prepare("SELECT judul, isi, tanggal_publish FROM artikel WHERE id = ?");
// Cek jika prepare query gagal
if ($stmt === false) {
die("Error mempersiapkan query: " . $koneksi->error);
}
// 2. Bind parameter: 'i' untuk integer, $id_artikel adalah nilai yang di-bind
$stmt->bind_param("i", $id_artikel);
// 3. Eksekusi query
$stmt->execute();
// 4. Dapatkan hasil
$result = $stmt->get_result();
if ($result->num_rows > 0) {
$row = $result->fetch_assoc();
echo "<h1>" . htmlspecialchars($row["judul"]) . "</h1>";
echo "<p class='meta'>Dipublikasikan pada: " . $row["tanggal_publish"] . "</p>";
echo "<p>" . nl2br(htmlspecialchars($row["isi"])) . "</p>";
} else {
echo "<p>Artikel tidak ditemukan.</p>";
}
// 5. Tutup statement
$stmt->close();
} else {
echo "<p>ID artikel tidak valid.</p>";
}
$koneksi->close();
?>
<p><a href="index.php">Kembali ke Daftar Artikel</a></p>
</div>
</body>
</html>
Penjelasan Prepared Statements:
$koneksi->prepare("SELECT ... WHERE id = ?");: Query SQL ditulis dengan placeholder?(tanda tanya) untuk setiap nilai yang akan disisipkan.$stmt->bind_param("i", $id_artikel);: Ini adalah langkah krusial.- Parameter pertama
"i"adalah string yang mendefinisikan tipe data dari parameter yang akan di-bind:iuntuk integer,suntuk string,duntuk double (float),buntuk blob. Jika ada lebih dari satu placeholder, Anda bisa menggunakan"is"untuk integer dan string. - Parameter kedua (dan seterusnya) adalah variabel yang nilainya akan diikat ke placeholder.
- Parameter pertama
$stmt->execute();: Mengeksekusi prepared statement dengan nilai yang sudah di-bind.$stmt->get_result();: Mengambil objek hasil dari eksekusi prepared statement, mirip dengan$koneksi->query().$stmt->close();: Penting untuk menutup statement setelah selesai, seperti menutup koneksi.
Dengan cara ini, input pengguna tidak akan pernah diinterpretasikan sebagai bagian dari kode SQL, melainkan sebagai data murni, sehingga memblokir potensi SQL Injection.
Pengalaman dan Pertimbangan Praktis
Sebagai seorang praktisi, ada beberapa hal yang perlu Anda pertimbangkan saat menampilkan data dari database:
1. Validasi Input
Meskipun prepared statements sangat membantu keamanan, validasi input di sisi aplikasi (PHP) tetap penting. Pastikan data yang masuk sesuai dengan ekspektasi Anda (misalnya, ID harus berupa angka, email harus format email valid, dll.). Contoh sederhana (int)$_GET['id'] adalah bentuk validasi tipe data.
2. Error Handling
Dalam proyek nyata, Anda tidak bisa hanya menggunakan die() untuk setiap error. Pertimbangkan untuk logging error, menampilkan pesan error yang ramah pengguna, atau mengarahkan ke halaman error khusus. Untuk query, Anda bisa memeriksa $koneksi->error atau $stmt->error untuk detail lebih lanjut.
3. Pagination untuk Data Besar
Jika tabel Anda memiliki ribuan atau jutaan baris data, menampilkan semuanya sekaligus akan sangat lambat dan membebani server serta browser pengguna. Implementasikan pagination (pembagian halaman) menggunakan klausa LIMIT dan OFFSET di SQL.
4. Performa Query
Pastikan query SQL Anda efisien. Gunakan INDEX pada kolom yang sering digunakan dalam klausa WHERE, ORDER BY, atau JOIN. Hindari SELECT * di production jika Anda hanya butuh beberapa kolom, sebutkan kolom yang spesifik.
5. mysqli vs PDO
mysqli (yang kita gunakan) adalah ekstensi yang secara spesifik dirancang untuk MySQL/MariaDB. Ada juga PDO (PHP Data Objects) yang menyediakan antarmuka universal untuk berbagai jenis database (MySQL, PostgreSQL, SQLite, dll.).
mysqli: Lebih cepat untuk MySQL karena lebih spesifik, namun hanya untuk MySQL.PDO: Lebih fleksibel (bisa ganti database tanpa banyak ubah kode), memiliki fitur yang lebih kaya dan konsisten.
Untuk project baru, banyak developer (termasuk saya) cenderung merekomendasikan PDO karena fleksibilitas dan API-nya yang sedikit lebih modern, meskipun mysqli dalam gaya object-oriented juga sangat baik dan aman.
Masalah yang Sering Terjadi
Dalam perjalanan menampilkan data database, ada beberapa masalah umum yang sering dihadapi developer:
1. Koneksi Database Gagal
- Gejala: Pesan error seperti “Koneksi gagal: Access denied for user ‘root’@’localhost’…” atau “Unknown database ‘db_blog'”.
- Penyebab:
- Password atau username salah.
- Nama database salah.
- Host database salah (misalnya, MySQL belum berjalan atau port berbeda).
- Solusi: Periksa kembali kredensial (host, user, pass, db name) di
koneksi.php. Pastikan server MySQL/MariaDB Anda berjalan.
2. Query SQL Error
- Gejala: Pesan error seperti “Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘…'”.
- Penyebab:
- Ada kesalahan penulisan dalam query SQL (misalnya, nama kolom atau tabel salah, tanda kutip tidak seimbang).
- Variabel PHP yang disisipkan ke query tidak diformat dengan benar (jika tidak menggunakan prepared statement).
- Solusi: Periksa kembali sintaks query SQL Anda. Gunakan
echo $sql;untuk melihat query yang terbentuk sebelum dieksekusi, lalu coba jalankan langsung di phpMyAdmin untuk debugging. Gunakan prepared statements untuk parameterisasi yang aman.
3. Data Tidak Muncul (Tidak Ada Hasil)
- Gejala: Halaman ditampilkan tapi tabel kosong, atau pesan “Tidak ada artikel yang ditemukan.” padahal seharusnya ada.
- Penyebab:
- Tabel benar-benar kosong (lupa input data).
- Klausa
WHEREterlalu spesifik atau tidak cocok dengan data yang ada. - Nama kolom di
$row["nama_kolom"]salah ketik. - Koneksi database terputus di tengah jalan (jarang tapi bisa).
- Solusi: Cek database langsung apakah datanya memang ada. Periksa query SQL Anda di phpMyAdmin. Pastikan nama kolom di kode PHP Anda sama persis dengan nama kolom di database (case-sensitive di beberapa sistem).
4. Karakter Tidak Tampil dengan Benar (Encoding Issue)
- Gejala: Karakter seperti ‘é’, ‘ü’, ‘ñ’ muncul sebagai simbol aneh (misalnya ‘�’).
- Penyebab: Inkonsistensi encoding antara database, tabel, koneksi, dan halaman HTML.
- Solusi:
- Pastikan database dan tabel Anda menggunakan encoding
utf8mb4. - Atur encoding koneksi PHP setelah terkoneksi:
$koneksi->set_charset("utf8mb4"); - Pastikan HTML Anda memiliki
<meta charset="UTF-8">di bagian<head>.
- Pastikan database dan tabel Anda menggunakan encoding
FAQ
Apa itu mysqli?
mysqli (MySQL Improved Extension) adalah ekstensi PHP yang menyediakan antarmuka untuk berinteraksi dengan database MySQL/MariaDB. Ini adalah versi yang lebih baru dan lebih baik dari ekstensi mysql lama (yang sudah deprecated) dan mendukung fitur-fitur MySQL modern seperti prepared statements dan transaksi.
Kapan saya harus menggunakan prepared statements?
Anda harus selalu menggunakan prepared statements kapan pun Anda menyisipkan variabel atau input pengguna ke dalam query SQL, baik itu untuk SELECT, INSERT, UPDATE, maupun DELETE. Ini adalah praktik terbaik untuk mencegah SQL Injection.
Apakah PDO lebih baik dari mysqli?
Baik PDO maupun mysqli adalah pilihan yang bagus. PDO menawarkan fleksibilitas untuk bekerja dengan berbagai jenis database, sementara mysqli spesifik untuk MySQL/MariaDB dan seringkali sedikit lebih cepat untuk database tersebut. Jika Anda berencana bekerja dengan MySQL saja, mysqli object-oriented sangat memadai. Jika Anda ingin fleksibilitas antar database, PDO adalah pilihan yang lebih baik.
Bagaimana cara menampilkan data yang sangat banyak (jutaan baris)?
Untuk data yang sangat banyak, Anda perlu mengimplementasikan pagination (pembagian halaman) menggunakan klausa LIMIT dan OFFSET pada query SQL Anda. Selain itu, pastikan server dan query Anda teroptimasi dengan baik, dan pertimbangkan caching.
Menutup koneksi database ($koneksi->close();) akan membebaskan sumber daya di server database yang dialokasikan untuk koneksi tersebut. Meskipun PHP secara otomatis menutup koneksi di akhir script, menutupnya secara eksplisit adalah praktik yang baik, terutama jika Anda memiliki banyak koneksi atau script yang berjalan lama.
Kesimpulan
Menampilkan data dari database adalah inti dari pengembangan aplikasi web dinamis. Dengan memahami cara membuat koneksi, mengeksekusi query SELECT, dan menampilkan hasilnya ke halaman HTML, Anda sudah menguasai fondasi penting. Lebih dari itu, selalu prioritaskan keamanan dengan menggunakan prepared statements untuk melindungi aplikasi Anda dari SQL Injection.
Teruslah berlatih, eksperimen dengan klausa SQL lainnya (JOIN, GROUP BY), dan jangan takut untuk mengeksplorasi lebih dalam tentang optimasi dan praktik terbaik database. Selamat mencoba!
TAGS: PHP, MySQL, Database, Web Development, mysqli, Tutorial, Coding, Backend, SQL Injection, Prepared Statements


