PHP

Cara Membuat CRUD PHP MySQL untuk Pemula

Pelajari cara membuat CRUD PHP MySQL menggunakan PDO: menambah, menampilkan, mengedit, dan menghapus data dengan prepared statement dan struktur sederhana untuk pemula.

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.

Topik: #CRUD #Database #MySQL #PDO #PHP #PHP Pemula

Artikel berikutnya

Cara Membuat Koneksi PHP ke MySQL dengan PDO