Setelah berhasil menghubungkan PHP ke MySQL menggunakan PDO, langkah berikutnya adalah membuat fitur CRUD.
CRUD adalah singkatan dari Create, Read, Update, dan Delete. Empat operasi ini menjadi dasar banyak aplikasi seperti sistem artikel, data siswa, produk, pelanggan, dan dashboard admin.
Apa Itu CRUD?
- Create — menambah data baru.
- Read — membaca atau menampilkan data.
- Update — mengubah data.
- Delete — menghapus data.
Dalam contoh ini kita akan menggunakan tabel sederhana bernama notes.
1. Membuat Tabel Database
CREATE TABLE notes (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(150) NOT NULL,
content TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
2. Membuat Koneksi PDO
Buat file config/database.php dengan kredensial milik environment kamu sendiri.
<?php
$dsn = "mysql:host=localhost;dbname=nama_database;charset=utf8mb4";
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
try {
$pdo = new PDO(
$dsn,
"user_database",
"PASSWORD_RAHASIA",
$options
);
} catch (PDOException $e) {
error_log($e->getMessage());
exit("Koneksi database gagal.");
}
?>
Jangan gunakan kredensial asli di repository publik atau screenshot.
3. Menampilkan Data
Buat index.php:
<?php
require __DIR__ . "/config/database.php";
$stmt = $pdo->query(
"SELECT id, title, content, created_at
FROM notes
ORDER BY id DESC"
);
$notes = $stmt->fetchAll();
?>
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<title>CRUD PHP MySQL</title>
</head>
<body>
<h1>Daftar Catatan</h1>
<a href="create.php">Tambah Catatan</a>
<?php foreach ($notes as $note): ?>
<article>
<h2>
<?= htmlspecialchars(
$note["title"],
ENT_QUOTES,
"UTF-8"
) ?>
</h2>
<p>
<?= nl2br(
htmlspecialchars(
$note["content"],
ENT_QUOTES,
"UTF-8"
)
) ?>
</p>
<a href="edit.php?id=<?= (int) $note["id"] ?>">
Edit
</a>
</article>
<?php endforeach; ?>
</body>
</html>
Kenapa Menggunakan htmlspecialchars()?
Data dari database belum tentu aman untuk langsung dimasukkan ke HTML. Ketika menampilkan teks biasa, lakukan escaping sesuai konteks agar karakter khusus tidak dianggap sebagai markup HTML.
4. Membuat Fitur Create
Buat create.php:
<?php
require __DIR__ . "/config/database.php";
$error = "";
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$title = trim($_POST["title"] ?? "");
$content = trim($_POST["content"] ?? "");
if ($title === "" || $content === "") {
$error = "Judul dan isi wajib diisi.";
} else {
$stmt = $pdo->prepare(
"INSERT INTO notes (title, content)
VALUES (:title, :content)"
);
$stmt->execute([
"title" => $title,
"content" => $content
]);
header("Location: index.php");
exit;
}
}
?>
<h1>Tambah Catatan</h1>
<?php if ($error !== ""): ?>
<p><?= htmlspecialchars($error, ENT_QUOTES, "UTF-8") ?></p>
<?php endif; ?>
<form method="post">
<label>
Judul
<input type="text" name="title" required>
</label>
<label>
Isi
<textarea name="content" required></textarea>
</label>
<button type="submit">Simpan</button>
</form>
5. Membuat Fitur Update
Buat edit.php:
<?php
require __DIR__ . "/config/database.php";
$id = filter_input(INPUT_GET, "id", FILTER_VALIDATE_INT);
if (!$id) {
exit("ID tidak valid.");
}
$stmt = $pdo->prepare(
"SELECT id, title, content
FROM notes
WHERE id = :id
LIMIT 1"
);
$stmt->execute(["id" => $id]);
$note = $stmt->fetch();
if (!$note) {
exit("Data tidak ditemukan.");
}
$error = "";
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$title = trim($_POST["title"] ?? "");
$content = trim($_POST["content"] ?? "");
if ($title === "" || $content === "") {
$error = "Judul dan isi wajib diisi.";
} else {
$stmt = $pdo->prepare(
"UPDATE notes
SET title = :title,
content = :content
WHERE id = :id"
);
$stmt->execute([
"title" => $title,
"content" => $content,
"id" => $id
]);
header("Location: index.php");
exit;
}
}
?>
<h1>Edit Catatan</h1>
<form method="post">
<input
type="text"
name="title"
value="<?= htmlspecialchars(
$note["title"],
ENT_QUOTES,
"UTF-8"
) ?>"
required
>
<textarea name="content" required><?=
htmlspecialchars(
$note["content"],
ENT_QUOTES,
"UTF-8"
)
?></textarea>
<button type="submit">Update</button>
</form>
6. Membuat Fitur Delete
Untuk operasi yang mengubah data, hindari menggunakan link GET seperti delete.php?id=1 sebagai mekanisme utama.
Gunakan form POST dan tambahkan perlindungan CSRF pada aplikasi nyata.
Contoh dasar delete.php:
<?php
require __DIR__ . "/config/database.php";
if ($_SERVER["REQUEST_METHOD"] !== "POST") {
http_response_code(405);
exit("Method tidak diizinkan.");
}
$id = filter_input(INPUT_POST, "id", FILTER_VALIDATE_INT);
if (!$id) {
exit("ID tidak valid.");
}
$stmt = $pdo->prepare(
"DELETE FROM notes WHERE id = :id"
);
$stmt->execute(["id" => $id]);
header("Location: index.php");
exit;
?>
Form tombol hapus:
<form method="post" action="delete.php">
<input
type="hidden"
name="id"
value="<?= (int) $note["id"] ?>"
>
<button type="submit">Hapus</button>
</form>
Prepared Statement pada CRUD
Semua query yang menerima nilai dinamis sebaiknya menggunakan prepared statement.
Contoh:
$stmt = $pdo->prepare(
"SELECT * FROM notes WHERE id = :id"
);
$stmt->execute([
"id" => $id
]);
Validasi Input
Prepared statement melindungi struktur query, tetapi bukan pengganti validasi bisnis.
Contoh hal yang perlu divalidasi:
- Field wajib tidak kosong.
- Panjang judul sesuai batas.
- ID berupa integer valid.
- Nilai status hanya berasal dari pilihan yang diizinkan.
CSRF pada Operasi Ubah dan Hapus
Untuk aplikasi yang memiliki login, operasi seperti Create, Update, dan Delete sebaiknya dilindungi dengan token CSRF.
Prinsip dasarnya adalah server membuat token acak untuk session, form mengirim token tersebut, lalu server memverifikasi token sebelum memproses perubahan.
Struktur Project Sederhana
crud/
├── config/
│ └── database.php
├── index.php
├── create.php
├── edit.php
└── delete.php
Kesalahan Umum Pemula
- Menyusun SQL dengan menggabungkan input pengguna.
- Tidak melakukan escaping saat menampilkan data.
- Menghapus data melalui GET.
- Tidak memeriksa apakah ID valid.
- Menampilkan pesan error database mentah ke pengunjung.
- Menyimpan kredensial database di repository publik.
Pengembangan Berikutnya
Setelah CRUD dasar bekerja, fitur dapat dikembangkan dengan:
- Pagination.
- Search.
- Filter.
- Login admin.
- CSRF protection.
- Flash message.
- Slug.
- Upload gambar.
Kesimpulan
CRUD adalah fondasi penting aplikasi database. Dengan PHP, PDO, dan MySQL, kita dapat membuat alur Create, Read, Update, dan Delete secara terstruktur.
Setelah CRUD, langkah berikutnya adalah mempelajari login PHP MySQL yang lebih aman, termasuk password hashing, session, dan prepared statement.
Artikel berikutnya untuk kamu
Belum ada rekomendasi lain.
Artikel berikutnya
Cara Membuat Koneksi PHP ke MySQL dengan PDO →