TUTORIAL LENGKAP · PEMULA → SIAP PAKAI

CRUD CodeIgniter 3 dengan Bootstrap 5 & MySQL

Belajar membangun aplikasi CRUD (Create, Read, Update, Delete) dari nol menggunakan CodeIgniter 3, tampilan modern Bootstrap 5, dan database MySQL. Studi kasus: Data Mahasiswa.

PHP 7.4+ / 8.x CodeIgniter 3.1.13 Bootstrap 5.3 MySQL / MariaDB Pola MVC

00Pengantar

CRUD adalah empat operasi dasar pada data: Create (tambah), Read (baca/tampil), Update (ubah), dan Delete (hapus). Hampir semua aplikasi — dari sistem akademik sampai e-commerce — bertumpu pada keempat operasi ini.

CodeIgniter 3 memakai pola MVC (Model-View-Controller) yang memisahkan logika jadi tiga bagian:

KomponenTugas
ModelBerurusan dengan database — query, insert, update, delete.
ViewTampilan / antarmuka yang dilihat user (HTML + Bootstrap).
ControllerJembatan: menerima request, panggil Model, kirim data ke View.

Yang akan kita bangun: tabel data mahasiswa yang bisa ditambah, diedit, dan dihapus, lengkap dengan validasi form dan flash message (notifikasi sukses/gagal).

01Persiapan & Instalasi

Pastikan kamu sudah punya web server lokal seperti XAMPP, Laragon, atau MAMP yang menyediakan Apache, PHP, dan MySQL.

Unduh CodeIgniter 3

Cara tercepat lewat Composer, atau unduh manual dari GitHub. Letakkan proyek di folder web root (misal htdocs untuk XAMPP atau www untuk Laragon).

Terminalbash
# Via Composer (disarankan)
composer create-project codeigniter/framework:^3.1 ci3_crud

# Atau clone langsung dari GitHub
git clone https://github.com/bcit-ci/CodeIgniter.git ci3_crud

Setelah itu, struktur folder utama yang penting hanya tiga: application/ (tempat kerja kita), system/ (inti framework, jangan diubah), dan index.php.

Cek instalasi berhasil dengan membuka http://localhost/ci3_crud/. Kalau muncul halaman "Welcome to CodeIgniter", berarti sudah siap.

02Membuat Database

Buka phpMyAdmin (http://localhost/phpmyadmin) lalu jalankan query SQL berikut untuk membuat database dan tabel mahasiswa:

SQL — phpMyAdminsql
CREATE DATABASE ci3_crud;

USE ci3_crud;

CREATE TABLE mahasiswa (
  id        INT AUTO_INCREMENT PRIMARY KEY,
  nim       VARCHAR(20)  NOT NULL,
  nama      VARCHAR(100) NOT NULL,
  jurusan   VARCHAR(100) NOT NULL,
  email     VARCHAR(100) NOT NULL,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- Data contoh (opsional)
INSERT INTO mahasiswa (nim, nama, jurusan, email) VALUES
('2021001', 'Ahmad Rian', 'Teknik Komputer', 'rian@mail.com'),
('2021002', 'Siti Aminah', 'Sistem Informasi', 'siti@mail.com');

03Konfigurasi CodeIgniter

Ada 4 file di folder application/config/ yang perlu kita sesuaikan agar CI terhubung ke database dan tahu controller default.

1. Base URL — config.php

config.php — application/config/php
$config['base_url'] = 'http://localhost/ci3_crud/';

2. Koneksi Database — database.php

database.php — application/config/php
$db['default'] = array(
    'dsn'      => '',
    'hostname' => 'localhost',
    'username' => 'root',
    'password' => '',           // kosongkan utk XAMPP default
    'database' => 'ci3_crud',
    'dbdriver' => 'mysqli',
    'db_debug' => (ENVIRONMENT !== 'production'),
    'char_set' => 'utf8',
    'dbcollat' => 'utf8_general_ci',
    // ... biarkan opsi lainnya default
);

3. Autoload — autoload.php

Muat library & helper yang sering dipakai supaya tidak perlu di-load berulang di tiap controller.

autoload.php — application/config/php
$autoload['libraries'] = array('database', 'session', 'form_validation');

$autoload['helper']    = array('url', 'form');

4. Controller Default — routes.php

routes.php — application/config/php
$route['default_controller'] = 'Mahasiswa';

Library session wajib di-autoload karena kita pakai flashdata untuk notifikasi. form_validation dipakai untuk memvalidasi input form sebelum disimpan.

04Struktur Proyek

Berikut file-file yang akan kita buat (ditandai). Semua berada di dalam folder application/:

application/   controllers/     Mahasiswa.php   models/     Mahasiswa_model.php   views/     templates/       header.php       footer.php     mahasiswa/       index.php  # tampil + tabel data       form.php   # form tambah & edit

Penting: nama file Controller dan Model harus diawali huruf kapital (Mahasiswa.php, bukan mahasiswa.php). Ini aturan wajib CodeIgniter 3.

05Membuat Model

Model menampung semua query ke database. Kita pakai Query Builder CodeIgniter yang ringkas dan aman dari SQL injection.

Mahasiswa_model.php — application/models/php
<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Mahasiswa_model extends CI_Model
{
    private $table = 'mahasiswa';

    // READ: ambil semua data, terbaru di atas
    public function getAll()
    {
        return $this->db
            ->order_by('id', 'DESC')
            ->get($this->table)
            ->result();
    }

    // READ: ambil satu data berdasarkan id
    public function getById($id)
    {
        return $this->db
            ->get_where($this->table, ['id' => $id])
            ->row();
    }

    // CREATE
    public function insert($data)
    {
        return $this->db->insert($this->table, $data);
    }

    // UPDATE
    public function update($id, $data)
    {
        return $this->db
            ->where('id', $id)
            ->update($this->table, $data);
    }

    // DELETE
    public function delete($id)
    {
        return $this->db
            ->where('id', $id)
            ->delete($this->table);
    }
}
Method Query BuilderFungsi
get()SELECT semua baris dari tabel
get_where()SELECT dengan kondisi WHERE
result()Hasil sebagai array of objects
row()Hasil sebagai satu object
insert() / update() / delete()Operasi tulis ke database

06Template Bootstrap 5

Agar tidak menulis ulang <head> dan navbar di setiap halaman, kita pisahkan jadi header dan footer. Bootstrap 5 dimuat lewat CDN.

Header

header.php — views/templates/php + html
<!DOCTYPE html>
<html lang="id">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title><?= $title ?></title>
  <!-- Bootstrap 5 CSS -->
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body class="bg-light">
  <nav class="navbar navbar-dark bg-dark mb-4">
    <div class="container">
      <a class="navbar-brand" href="<?= base_url() ?>">🎓 SIMAK Kampus</a>
    </div>
  </nav>
  <div class="container">

Footer

footer.php — views/templates/php + html
  </div> <!-- /container -->
  <!-- Bootstrap 5 JS Bundle -->
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

Fungsi base_url() dari URL helper otomatis menghasilkan URL absolut dari base_url yang sudah kita set di config.php — jadi link tidak akan rusak saat aplikasi dipindah.

07Membuat Controller

Controller Mahasiswa mengatur semua alur. Di __construct() kita load Model sekali, lalu pakai di semua method. Mari lihat kerangkanya dulu, baru tiap method dibahas per operasi CRUD di bawah.

Mahasiswa.php — application/controllers/php
<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Mahasiswa extends CI_Controller
{
    public function __construct()
    {
        parent::__construct();
        // load model, beri alias 'mhs' biar singkat
        $this->load->model('Mahasiswa_model', 'mhs');
    }

    // method index(), create(), edit(), delete() menyusul...
}

08Read — Menampilkan Data

Method index() mengambil semua mahasiswa dari Model lalu mengirimnya ke View.

Mahasiswa.php — method index()php
public function index()
{
    $data['title']     = 'Data Mahasiswa';
    $data['mahasiswa'] = $this->mhs->getAll();

    $this->load->view('templates/header', $data);
    $this->load->view('mahasiswa/index', $data);
    $this->load->view('templates/footer');
}

Lalu View index.php menampilkan data dalam tabel Bootstrap. Perhatikan blok flashdata di atas untuk notifikasi:

index.php — views/mahasiswa/php + html
<div class="d-flex justify-content-between align-items-center mb-3">
  <h3>📚 Daftar Mahasiswa</h3>
  <a href="<?= base_url('mahasiswa/create') ?>" class="btn btn-primary">
    + Tambah Data
  </a>
</div>

<!-- Flash message (notifikasi) -->
<?php if ($this->session->flashdata('pesan')): ?>
  <div class="alert alert-success alert-dismissible fade show">
    <?= $this->session->flashdata('pesan') ?>
    <button class="btn-close" data-bs-dismiss="alert"></button>
  </div>
<?php endif; ?>

<table class="table table-bordered table-striped bg-white">
  <thead class="table-dark">
    <tr>
      <th>No</th><th>NIM</th><th>Nama</th>
      <th>Jurusan</th><th>Email</th><th width="160">Aksi</th>
    </tr>
  </thead>
  <tbody>
    <?php $no = 1; foreach ($mahasiswa as $m): ?>
    <tr>
      <td><?= $no++ ?></td>
      <td><?= $m->nim ?></td>
      <td><?= $m->nama ?></td>
      <td><?= $m->jurusan ?></td>
      <td><?= $m->email ?></td>
      <td>
        <a href="<?= base_url('mahasiswa/edit/'.$m->id) ?>"
           class="btn btn-warning btn-sm">Edit</a>
        <a href="<?= base_url('mahasiswa/delete/'.$m->id) ?>"
           class="btn btn-danger btn-sm"
           onclick="return confirm('Yakin hapus data ini?')">Hapus</a>
      </td>
    </tr>
    <?php endforeach; ?>
  </tbody>
</table>

Di produksi, bungkus output data dengan htmlspecialchars() atau gunakan helper html_escape() untuk mencegah serangan XSS. Contoh: <?= html_escape($m->nama) ?>

09Create — Menambah Data

Satu method create() menangani dua hal: menampilkan form (GET) dan memproses simpan (setelah submit). Validasi dijalankan dulu sebelum data masuk database.

Mahasiswa.php — method create()php
public function create()
{
    // aturan validasi
    $this->form_validation->set_rules('nim',     'NIM',     'required');
    $this->form_validation->set_rules('nama',    'Nama',    'required');
    $this->form_validation->set_rules('jurusan', 'Jurusan', 'required');
    $this->form_validation->set_rules('email',   'Email',   'required|valid_email');

    if ($this->form_validation->run() === FALSE) {
        // validasi gagal / form belum disubmit -> tampilkan form
        $data['title']  = 'Tambah Mahasiswa';
        $data['aksi']   = base_url('mahasiswa/create');
        $data['mhs']    = null; // mode tambah
        $this->load->view('templates/header', $data);
        $this->load->view('mahasiswa/form', $data);
        $this->load->view('templates/footer');
    } else {
        // validasi lolos -> simpan
        $data = [
            'nim'     => $this->input->post('nim', TRUE),
            'nama'    => $this->input->post('nama', TRUE),
            'jurusan' => $this->input->post('jurusan', TRUE),
            'email'   => $this->input->post('email', TRUE),
        ];
        $this->mhs->insert($data);
        $this->session->set_flashdata('pesan', 'Data berhasil ditambahkan!');
        redirect('mahasiswa');
    }
}

View Form (dipakai bersama untuk Tambah & Edit)

form.php — views/mahasiswa/php + html
<h3><?= $title ?></h3>

<!-- tampilkan error validasi -->
<?= validation_errors('<div class="alert alert-danger">', '</div>') ?>

<form method="post" action="<?= $aksi ?>" class="card card-body bg-white">
  <div class="mb-3">
    <label class="form-label">NIM</label>
    <input type="text" name="nim" class="form-control"
           value="<?= $mhs->nim ?? set_value('nim') ?>">
  </div>
  <div class="mb-3">
    <label class="form-label">Nama</label>
    <input type="text" name="nama" class="form-control"
           value="<?= $mhs->nama ?? set_value('nama') ?>">
  </div>
  <div class="mb-3">
    <label class="form-label">Jurusan</label>
    <input type="text" name="jurusan" class="form-control"
           value="<?= $mhs->jurusan ?? set_value('jurusan') ?>">
  </div>
  <div class="mb-3">
    <label class="form-label">Email</label>
    <input type="email" name="email" class="form-control"
           value="<?= $mhs->email ?? set_value('email') ?>">
  </div>
  <button class="btn btn-primary">Simpan</button>
  <a href="<?= base_url('mahasiswa') ?>" class="btn btn-secondary">Batal</a>
</form>

$mhs->nim ?? set_value('nim') — operator null coalescing (??) bikin form ini serbaguna: kalau mode edit isi otomatis dari data lama, kalau mode tambah isi dari input sebelumnya bila validasi gagal. Satu file untuk dua keperluan!

10Update — Mengubah Data

Method edit($id) mirip create(), bedanya: data lama diambil dulu dengan getById(), dan saat simpan memakai update().

Mahasiswa.php — method edit()php
public function edit($id)
{
    $mhs = $this->mhs->getById($id);
    if (!$mhs) show_404(); // data tidak ditemukan

    $this->form_validation->set_rules('nim',     'NIM',     'required');
    $this->form_validation->set_rules('nama',    'Nama',    'required');
    $this->form_validation->set_rules('jurusan', 'Jurusan', 'required');
    $this->form_validation->set_rules('email',   'Email',   'required|valid_email');

    if ($this->form_validation->run() === FALSE) {
        $data['title'] = 'Edit Mahasiswa';
        $data['aksi']  = base_url('mahasiswa/edit/'.$id);
        $data['mhs']   = $mhs; // data lama untuk mengisi form
        $this->load->view('templates/header', $data);
        $this->load->view('mahasiswa/form', $data);
        $this->load->view('templates/footer');
    } else {
        $data = [
            'nim'     => $this->input->post('nim', TRUE),
            'nama'    => $this->input->post('nama', TRUE),
            'jurusan' => $this->input->post('jurusan', TRUE),
            'email'   => $this->input->post('email', TRUE),
        ];
        $this->mhs->update($id, $data);
        $this->session->set_flashdata('pesan', 'Data berhasil diperbarui!');
        redirect('mahasiswa');
    }
}

Karena View form.php sudah dirancang fleksibel di langkah Create, kita tidak perlu membuat view baru. Tombol Edit di tabel sudah mengarah ke mahasiswa/edit/{id}.

11Delete — Menghapus Data

Method delete($id) paling sederhana: hapus data lalu kembali ke daftar. Konfirmasi confirm() sudah dipasang di tombol pada tabel (langkah Read).

Mahasiswa.php — method delete()php
public function delete($id)
{
    if (!$this->mhs->getById($id)) show_404();

    $this->mhs->delete($id);
    $this->session->set_flashdata('pesan', 'Data berhasil dihapus!');
    redirect('mahasiswa');
}

Menghapus lewat link GET seperti ini cocok untuk belajar. Untuk aplikasi produksi, gunakan method POST + CSRF token agar tidak bisa dipicu lewat URL sembarangan.

12Menjalankan Aplikasi

Semua komponen sudah lengkap! Berikut ringkasan rute (URL) yang sekarang aktif:

URLMethod ControllerFungsi
/mahasiswaindex()Tampil semua data
/mahasiswa/createcreate()Form tambah + simpan
/mahasiswa/edit/{id}edit($id)Form edit + update
/mahasiswa/delete/{id}delete($id)Hapus data

Buka di browser:

Browserurl
http://localhost/ci3_crud/mahasiswa
🎉

Selesai! Aplikasi CRUD CodeIgniter 3 + Bootstrap 5 + MySQL kamu sudah berjalan penuh: bisa menambah, melihat, mengedit, dan menghapus data mahasiswa, lengkap dengan validasi dan notifikasi.

Langkah Pengembangan Lanjutan

  • Validasi unik NIM — tambahkan rule is_unique[mahasiswa.nim] agar tidak ada NIM ganda.
  • Pagination — pakai library pagination CI bila data sudah banyak.
  • Pencarian & filter — tambahkan kolom search di atas tabel.
  • Upload foto — gunakan library upload untuk menyimpan foto mahasiswa.
  • Keamanan — aktifkan $config['csrf_protection'] = TRUE; dan ganti hapus ke POST.