Tutorial PHP #30: Mini Project PHP Native

1. Tujuan Mini Project

Setelah mempelajari 29 tutorial sebelumnya, saatnya menggabungkan semua materi ke dalam satu mini project nyata. Kita akan membangun aplikasi manajemen artikel sederhana dengan fitur login, CRUD, dan session.

Dengan mengerjakan project ini, kamu akan memahami bagaimana berbagai konsep PHP bekerja bersama dalam aplikasi yang sesungguhnya.

2. Fitur Aplikasi

  • Register dan login user
  • Dashboard setelah login
  • Daftar artikel (Read)
  • Tambah artikel baru (Create)
  • Edit artikel (Update)
  • Hapus artikel (Delete)
  • Logout

3. Struktur Folder Project

mini-project/
├── config/
│   └── database.php       - koneksi PDO
├── includes/
│   ├── auth.php           - helper cek login
│   ├── header.php         - template header
│   └── footer.php         - template footer
├── public/
│   └── assets/
│       └── style.css
├── index.php              - daftar artikel (redirect ke login jika belum login)
├── login.php              - form login
├── register.php           - form register
├── logout.php             - proses logout
├── artikel/

│   ├── create.php         - tambah artikel
│   ├── edit.php           - edit artikel
│   └── delete.php         - hapus artikel
└── README.md

4. Setup Database

CREATE DATABASE mini_project;
USE mini_project;

CREATE TABLE users (
    id         INT AUTO_INCREMENT PRIMARY KEY,
    nama       VARCHAR(100) NOT NULL,
    email      VARCHAR(150) NOT NULL UNIQUE,
    password   VARCHAR(255) NOT NULL,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE artikel (
    id         INT AUTO_INCREMENT PRIMARY KEY,
    user_id    INT NOT NULL,
    judul      VARCHAR(200) NOT NULL,
    konten     TEXT NOT NULL,
    status     ENUM("draft", "published") DEFAULT "draft",
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME ON UPDATE CURRENT_TIMESTAMP,
    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);

5. File Koneksi Database

<?php
// config/database.php
define("DB_HOST", "localhost");
define("DB_NAME", "mini_project");
define("DB_USER", "root");
define("DB_PASS", "");

try {
    $pdo = new PDO(
        "mysql:host=" . DB_HOST . ";dbname=" . DB_NAME . ";charset=utf8mb4",
        DB_USER, DB_PASS,
        [
            PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        ]
    );
} catch (PDOException $e) {
    die("Koneksi gagal: " . $e->getMessage());
}
?>

6. Helper Auth

<?php
// includes/auth.php
function requireLogin(): void {
    if (session_status() === PHP_SESSION_NONE) session_start();
    if (empty($_SESSION["logged_in"])) {
        header("Location: /mini-project/login.php");
        exit;
    }
}

function currentUser(): array {
    return [
        "id"    => $_SESSION["user_id"]   ?? 0,
        "nama"  => $_SESSION["user_nama"] ?? "Guest",
        "email" => $_SESSION["user_email"] ?? "",
    ];
}
?>

7. Halaman Index - Daftar Artikel

<?php
session_start();
require_once __DIR__ . "/includes/auth.php";
require_once __DIR__ . "/config/database.php";
requireLogin();

$user = currentUser();

// Ambil artikel milik user yang sedang login
$stmt = $pdo->prepare(
    "SELECT * FROM artikel WHERE user_id = :uid ORDER BY created_at DESC"
);
$stmt->execute(["uid" => $user["id"]]);
$artikels = $stmt->fetchAll();
?>
<!DOCTYPE html>
<html lang="id">
<head><title>Artikel Saya</title></head>
<body>
<h1>Halo, <?= htmlspecialchars($user["nama"]) ?>!</h1>
<a href="artikel/create.php">+ Tambah Artikel</a> |
<a href="logout.php">Logout</a>
<hr>

<?php if (empty($artikels)): ?>
    <p>Belum ada artikel. <a href="artikel/create.php">Buat yang pertama!</a></p>
<?php else: ?>
    <table border="1" cellpadding="8">
        <tr><th>Judul</th><th>Status</th><th>Tanggal</th><th>Aksi</th></tr>
        <?php foreach ($artikels as $art): ?>
        <tr>
            <td><?= htmlspecialchars($art["judul"]) ?></td>
            <td><?= $art["status"] ?></td>
            <td><?= date("d M Y", strtotime($art["created_at"])) ?></td>
            <td>
                <a href="artikel/edit.php?id=<?= $art["id"] ?>">Edit</a> |
                <a href="artikel/delete.php?id=<?= $art["id"] ?>"
                   onclick="return confirm(''Hapus artikel ini?'')">Hapus</a>
            </td>
        </tr>
        <?php endforeach; ?>
    </table>
<?php endif; ?>
</body>
</html>

8. Create Artikel

<?php
session_start();
require_once __DIR__ . "/../includes/auth.php";
require_once __DIR__ . "/../config/database.php";
requireLogin();

$errors = [];
$user   = currentUser();

if ($_SERVER["REQUEST_METHOD"] === "POST") {
    $judul  = trim($_POST["judul"]  ?? "");
    $konten = trim($_POST["konten"] ?? "");
    $status = in_array($_POST["status"] ?? "", ["draft", "published"])
              ? $_POST["status"] : "draft";

    if (empty($judul))  $errors[] = "Judul wajib diisi";
    if (empty($konten)) $errors[] = "Konten wajib diisi";

    if (empty($errors)) {
        $stmt = $pdo->prepare(
            "INSERT INTO artikel (user_id, judul, konten, status) VALUES (:uid, :judul, :konten, :status)"
        );
        $stmt->execute([
            "uid"    => $user["id"],
            "judul"  => $judul,
            "konten" => $konten,
            "status" => $status,
        ]);

        header("Location: /mini-project/index.php?msg=created");
        exit;
    }
}
?>
<h2>Tambah Artikel</h2>
<?php foreach ($errors as $e): ?>
    <p style="color:red"><?= htmlspecialchars($e) ?></p>
<?php endforeach; ?>
<form method="POST">
    <input type="text" name="judul" placeholder="Judul artikel" style="width:100%"><br><br>
    <textarea name="konten" rows="10" style="width:100%"></textarea><br><br>
    <select name="status">
        <option value="draft">Draft</option>
        <option value="published">Published</option>
    </select><br><br>
    <button type="submit">Simpan</button>
    <a href="/mini-project/index.php">Batal</a>
</form>

9. Materi PHP yang Dipakai di Project Ini

  • Sintaks dasar, variabel, operator
  • Percabangan dan perulangan
  • Function dan scope variabel
  • Array dan string handling
  • Form handling (GET & POST) dan validasi input
  • include / require untuk modularisasi kode
  • Superglobal ($_POST, $_GET, $_SESSION, $_SERVER)
  • Session untuk autentikasi
  • PDO untuk koneksi dan operasi database
  • CRUD (Create, Read, Update, Delete)
  • OOP dasar untuk struktur helper

10. Langkah Selanjutnya

Setelah menyelesaikan mini project ini, kamu bisa mengembangkannya lebih lanjut:

  • Tambah fitur upload gambar untuk artikel
  • Tambah pagination untuk daftar artikel
  • Tambah fitur search artikel
  • Refactor kode ke arsitektur MVC sederhana
  • Lanjut ke framework Laravel untuk pengembangan yang lebih modern dan terstruktur

Selamat! Kamu telah menyelesaikan seluruh seri tutorial PHP Native. Fondasi yang kamu bangun di sini akan sangat membantu saat belajar framework PHP seperti Laravel atau CodeIgniter.


ariq fadhil

Im Ariq Tech, a Top Rated Fullstack Developer with 5+ years of experience, delivering high-quality solutions across 50+ projects.