Di episode #68 kemarin CodeIgniter 4 sudah terpasang dan menyala di localhost:8080. Sekarang pertanyaan serunya: bagaimana caranya membuat halaman sendiri? Bagaimana URL /menu bisa menampilkan daftar menu, dan URL /menu/3 menampilkan detail menu nomor 3?
Jawabannya melibatkan tiga komponen yang bekerja berantai: routing (penerjemah URL), controller (pengambil keputusan), dan view (penyaji tampilan). Tiga serangkai ini adalah jantung pola MVC, dan memahaminya di CodeIgniter berarti kamu memahami cara kerja hampir semua framework web di dunia.
Analoginya seperti restoran. Routing adalah pelayan yang menerima pesanan dan tahu pesanan itu untuk meja berapa. Controller adalah kepala koki yang memutuskan apa yang harus dimasak dan bahan apa yang disiapkan. View adalah hidangan yang disajikan ke meja, cantik dan siap santap. Pelayan tidak memasak, koki tidak mengantar, penyaji tidak memutuskan menu. Masing-masing punya peran, dan kekacauan dimulai saat peran itu dicampuraduk.
Alur Request: Perjalanan Satu Klik
Saat pengunjung membuka http://localhost:8080/menu, inilah yang terjadi di dalam CodeIgniter:
- Request masuk lewat
public/index.php(front controller, seperti yang kamu tebak di episode #68). - Framework membuka
app/Config/Routes.phpdan mencari aturan yang cocok dengan URL/menu. - Aturan yang cocok menunjuk ke sebuah controller dan method, misalnya
Menu::index. - Controller bekerja: mengambil data, mengolahnya, lalu memanggil view.
- View merender HTML dan dikirim kembali ke browser.
Lima langkah ini terjadi dalam milidetik untuk setiap halaman. Kalau ada yang error, kamu sekarang tahu di langkah mana mencarinya: URL tidak ketemu berarti masalah routing, data tidak muncul berarti masalah controller, tampilan rusak berarti masalah view.
Routing: Penerjemah URL
Buka app/Config/Routes.php. Di dalamnya ada baris seperti ini:
$routes->get('/', 'Home::index');
Artinya: request GET ke URL / ditangani oleh method index() di controller Home. Untuk halaman daftar menu, tambahkan:
$routes->get('menu', 'Menu::index');
$routes->get('menu/(:num)', 'Menu::detail/$1');
Baris kedua memakai placeholder (:num) yang artinya "angka apa pun". Tulisannya $1 berarti "teruskan angka yang cocok itu sebagai parameter pertama ke method detail". Jadi URL /menu/3 akan memanggil Menu::detail(3).
Placeholder lain yang tersedia: (:segment) untuk satu segmen teks apa pun, (:any) untuk apa pun termasuk garis miring, dan (:alpha) untuk huruf saja. Pilih yang paling ketat sesuai kebutuhanmu: (:num) untuk ID jauh lebih aman daripada (:any).
Satu aturan penting: CodeIgniter membaca route dari atas ke bawah dan memakai yang pertama cocok. Jadi route yang spesifik harus ditulis di atas route yang umum. Kalau (:any) ditulis paling atas, ia akan "memakan" semua URL di bawahnya.
Berhenti dan tebak dulu! Dengan route di bawah ini, method apa yang dipanggil saat pengunjung membuka /menu/nasi-goreng?
$routes->get('menu/(:num)', 'Menu::detail/$1');
$routes->get('menu/(:segment)', 'Menu::cari/$1');
Controller: Kepala Koki Aplikasi
Controller tinggal di app/Controllers dan biasanya extends BaseController. Tugasnya: menerima request, memutuskan apa yang harus dilakukan, dan mengembalikan respons. Contoh controller menu sederhana:
<?php
namespace App\Controllers;
class Menu extends BaseController
{
public function index()
{
$data = [
'title' => 'Daftar Menu',
'menus' => ['Nasi Goreng', 'Mie Goreng', 'Es Teh'],
];
return view('menu/index', $data);
}
public function detail($id)
{
return "Detail menu nomor $id";
}
}
Perhatikan method index(): ia menyiapkan array $data, lalu mengembalikan hasil view(). Kata "mengembalikan" ini penting dan sering dilupakan pemula.
Berhenti dan tebak dulu! Apa yang terjadi kalau kamu menulis view('menu/index', $data); tanpa kata return di depannya?
public function index()
{
$data = ['title' => 'Daftar Menu'];
view('menu/index', $data); // tanpa return!
}
View: Wajah yang Disajikan
View adalah file PHP biasa di app/Views. Buat app/Views/menu/index.php:
<h1><?= esc($title) ?></h1>
<ul>
<?php foreach ($menus as $m): ?>
<li><?= esc($m) ?></li>
<?php endforeach ?>
</ul>
Data dikirim dari controller lewat array asosiatif di parameter kedua view(): kunci 'title' otomatis menjadi variabel $title di view, kunci 'menus' menjadi $menus. Sederhana dan eksplisit, tidak ada sihir.
Fungsi esc() wajib diperhatikan. Ia membersihkan output supaya aman dari serangan XSS (cross-site scripting): kalau nama menu berisi kode JavaScript jahat kiriman pengguna iseng, esc() menetralkannya jadi teks biasa. Aturannya: setiap data yang berasal dari luar dan ditampilkan ke browser harus lewat esc(). Tanpa kecuali.
Supaya tidak menulis kerangka HTML berulang di setiap view, CodeIgniter punya sistem layout. Buat layout dasar sekali, lalu tiap view "menumpang" di dalamnya:
<!-- app/Views/layouts/main.php -->
<html><head><title><?= esc($title ?? 'Kantin Online') ?></title></head>
<body>
<?= $this->renderSection('content') ?>
</body></html>
<!-- app/Views/menu/index.php -->
<?= $this->extend('layouts/main') ?>
<?= $this->section('content') ?>
<h1>Daftar Menu</h1>
<?= $this->endSection() ?>
Pola extend dan section ini mirip dengan template engine di framework lain, termasuk Blade di Laravel nanti. Sekali paham di sini, pindah ke Laravel terasa familiar.
Kapan layout layak dibuat? Begitu kamu punya lebih dari dua halaman yang berbagi kerangka yang sama: header, navigasi, dan footer yang identik. Tanpa layout, mengubah satu link navigasi berarti mengedit semua file view satu per satu. Dengan layout, cukup satu file. Ini penerapan prinsip DRY (don't repeat yourself) di lapisan tampilan, dan ia menghemat banyak waktu saat aplikasi mulai punya belasan halaman.
Dua hal yang perlu diluruskan sebelum lanjut. Mitos pertama: "URL harus sama dengan nama file". Itu pola pikir PHP native, di mana menu.php diakses lewat /menu.php. Di framework, routing memisahkan URL dari struktur file. URL /menu/3 tidak berarti ada file bernama 3, ia hanya pola yang diterjemahkan route. Kebebasan ini memungkinkan URL yang cantik dan aman.
Mitos kedua: "logika boleh ditulis di view biar cepat". Godaannya besar: tinggal selipkan query database di tengah HTML. Tapi view yang berisi logika bisnis adalah awal dari kode spaghetti yang tidak bisa diuji dan sulit diubah. Aturannya keras: view hanya menampilkan, controller memutuskan, model mengakses data. Model akan kita bahas tuntas di episode #70.
Kuis Cepat
Kuis cepat: Pengunjung membuka /produk/25 dan route-nya $routes->get('produk/(:num)', 'Produk::lihat/$1'). Apa yang terjadi?
Latihan: Halaman Menu Kantin Versimu
- Buat controller
Menudengan methodindex()dandetail($id)seperti contoh di atas. - Daarkan route untuk
/menudan/menu/(:num)diapp/Config/Routes.php. Pastikan route yang spesifik ditulis di atas yang umum. - Buat view
menu/index.phpyang menampilkan daftar menu dari array, lengkap denganesc()di setiap output. - Ubah, jangan cuma salin: tambahkan layout
layouts/main.php, lalu ubah view-mu memakaiextenddansection. Refresh dan pastikan tampilannya tetap benar. - Eksperimen: sengaja hapus kata
returndi controller, refresh browser, dan amati halaman kosongnya. Kembalikan lagi. Pengalaman langsung ini lebih menancap daripada sekadar membaca. - Tantangan: buat route
/cari/(:segment)yang menampilkan "Kamu mencari: ..." sesuai teks di URL. Coba buka/cari/nasi-goreng.
Di episode #70, Model dan Query Builder di CodeIgniter, rantai MVC kita lengkap: controller tidak lagi memakai array khayalan, tapi mengambil data beneran dari database lewat model. Ilmu SQL dari seri kemarin akhirnya tampil di panggung framework.
Diskusi & Komentar 0
Punya tanggapan, pertanyaan, atau tips seputar tutorial ini? Tulis komentar kamu di bawah!
Jadilah yang pertama membuka obrolan dan berbagi pandangan seputar tutorial resep kode ini.
Tulis Komentar
Komentar menggunakan akun Google. Harap berkomentar dengan santun dan berbobot.