Laravel Dasar
Target: pemula yang sudah memahami dasar PHP dan ingin belajar Laravel secara bertahap dari fondasi HTTP hingga arsitektur aplikasi. Versi: Laravel 11 / 12 (PHP 8.2+) Prasyarat: PHP Dasar · PHP OOP Fokus modul pembelajaran ini: instalasi → Artisan → routing → Blade view → controller → request & input → validation → response & redirect → session & cookies → middleware → CSRF → route groups → storage & file upload → error handling → testing → environment & config → dependency injection → service container & provider → facades → maintenance mode → mini project.
Cara Belajar
🟢 Fundamental
→ wajib dipahami untuk mulai membuat aplikasi web Laravel
🟡 Lanjutan
→ pelajari setelah alur request-response dasar sudah nyaman
🔴 Operasional
→ penting saat mengelola aplikasi di server / productionMental model alur HTTP request di Laravel:
Browser Request
│
│ URL: /users
▼
routes/web.php
│
│ mencocokkan route
▼
Middleware Pipeline (Auth, CSRF, Session)
│
│ lolos filter
▼
Controller (UserController@store)
│
│ validasi request input
▼
Request Validation
│
│ proses logika aplikasi
▼
Response (Blade View / JSON / Redirect)
│
▼
Browser Menerima Tampilan (HTML / JSON)Hafalan:
Route → menentukan alamat URL
Middleware → menyaring dan memvalidasi request
Controller → memproses logika dan data
Blade View → menampilkan antarmuka HTML
Response → hasil akhir yang dikirim ke browserDaftar Isi
🟢 Fundamental
- Pengenalan Laravel
- Membuat Project & Instalasi
- Menjalankan Server & Vite
- Struktur Direktori Project
- Mengenal Artisan CLI
- Route Pertama & Closure
- HTTP Routing Methods
- View & Blade Templating Dasar
- Layout Blade & Asset Vite
- Route Parameters
- Named Routes & URL Generator
- Controller
- HTTP Request Object
- Mengambil Data Input Request
- Form Validation Dasar
- Form Request Validation
- HTTP Responses
- HTTP Redirects
- Session & Flash Data
- Cookies
- Middleware Dasar
- Mendaftarkan Middleware
- CSRF Protection
- Route Groups & Prefixes
- File Storage Disk
- File Upload Handling
- Error Handling & Custom Error Pages
- HTTP Exceptions
- Testing Dasar
- Environment Configuration (.env)
- Application Environment & Debug Mode
- File Konfigurasi Laravel
- Configuration Caching
🟡 Lanjutan
🔴 Operasional
🛠️ Referensi & Praktik
- Peta Ingatan Cepat
- Tabel Ringkasan
- Cheat Code Laravel Dasar 10 Detik
- Urutan Belajar yang Disarankan
- Mini Project: CRUD Sederhana User Portal
- Referensi Resmi
1. 🟢 Pengenalan Laravel
Konsep
Laravel adalah web application framework berbasis PHP dengan sintaks yang ekspresif, elegan, dan terstruktur. Laravel menangani kebutuhan umum aplikasi web seperti routing, otentikasi, validasi, sesi, caching, dan interaksi basis data.
Diagram Alur Eksekusi
Browser User
│
│ HTTP Request
▼
public/index.php (Entry Point)
│
│ bootstrap framework
▼
Route Matching & Middleware
│
│ dispatch
▼
Controller Action
│
│ generate output
▼
HTTP Response (HTML / JSON)Route Paling Sederhana
use Illuminate\Support\Facades\Route;
Route::get('/hello', function () {
return 'Hello Laravel';
});Hafalan:
Laravel → framework PHP modern untuk membangun aplikasi web & REST API2. 🟢 Membuat Project & Instalasi
Konsep
Laravel membutuhkan PHP (versi 8.2+) dan dependency manager Composer.
1. Membuat Project dengan Composer
composer create-project laravel/laravel belajar-laravelMasuk ke direktori:
cd belajar-laravel2. Alternatif: Menggunakan Laravel Installer
laravel new belajar-laravel3. Menyiapkan Dependensi Frontend
npm installHafalan:
composer create-project laravel/laravel nama-app → install Laravel baru
composer install → install dependensi PHP
npm install → install dependensi frontend / Vite3. 🟢 Menjalankan Server & Vite
Konsep
Laravel menyediakan built-in web server melalui Artisan untuk proses development lokal.
1. Menjalankan Server PHP
php artisan serveAplikasi dapat dibuka di browser pada alamat:
http://127.0.0.1:80002. Menjalankan Asset Server Vite (Frontend)
npm run devUntuk build production asset (CSS/JS minified):
npm run buildDiagram Alur Server Development
php artisan serve ──> Melayani backend PHP (Port 8000)
npm run dev ──> Melayani Hot Reload CSS & JS (Vite)Hafalan:
php artisan serve → jalankan web server backend
npm run dev → jalankan asset server frontend4. 🟢 Struktur Direktori Project
Konsep
Laravel memiliki struktur folder yang rapi dan terstandarisasi:
belajar-laravel/
├── app/ <── Kode utama aplikasi (Controller, Model, Middleware)
│ ├── Http/
│ │ ├── Controllers/
│ │ └── Requests/
│ ├── Models/
│ └── Providers/
├── bootstrap/ <── Bootstrap framework & bootstrap/app.php
├── config/ <── File-file konfigurasi aplikasi
├── database/ <── Migrations, factories, seeders
├── public/ <── Document root publik & index.php
├── resources/ <── Blade views, raw CSS, JS
│ └── views/
├── routes/ <── Definisi rute web.php & console.php
├── storage/ <── Log aplikasi, cache, uploaded files
├── tests/ <── Automated tests (Feature & Unit)
├── .env <── Konfigurasi environment lokal
├── artisan <── File CLI Artisan
└── composer.json <── Dependensi PHPRingkasan Fungsi Direktori Utama
| Direktori | Fungsi Utama |
|---|---|
app/Http/Controllers | Tempat menyimpan class Controller |
app/Models | Tempat menyimpan class Eloquent Model |
bootstrap/app.php | Konfigurasi routing, middleware, dan exception handler (Laravel modern) |
config/ | Kumpulan file setting/konfigurasi aplikasi |
resources/views/ | Tempat file template antarmuka Blade (.blade.php) |
routes/web.php | Tempat mendaftarkan rute web berbasis browser |
storage/ | Tempat penyimpanan file runtime, session file, dan log |
Hafalan:
app/ → kode logika aplikasi
resources/ → tampilan Blade & asset
routes/ → daftar URL aplikasi
config/ → setting aplikasi5. 🟢 Mengenal Artisan CLI
Konsep
Artisan adalah antarmuka baris perintah (Command Line Interface) bawaan Laravel yang menyediakan perintah pembantu (generator) dan utilitas maintenance.
Perintah Penting Artisan
# Menampilkan semua daftar command
php artisan list
# Menampilkan informasi rute yang terdaftar
php artisan route:list
# Membuat Controller baru
php artisan make:controller UserController
# Membuat Model baru
php artisan make:model Product
# Membuat Model sekaligus file Migration
php artisan make:model Product -m
# Membuat Middleware
php artisan make:middleware EnsureTokenIsValid
# Membuat Form Request Validation
php artisan make:request StoreUserRequest
# Menjalankan automated tests
php artisan test
# Menampilkan status detail aplikasi & environment
php artisan aboutHafalan:
php artisan make:controller → buat controller
php artisan route:list → lihat semua rute
php artisan test → jalankan testing6. 🟢 Route Pertama & Closure
Konsep
Route menghubungkan metode HTTP dan URL yang diminta browser ke sebuah aksi (handler).
Menulis Route di routes/web.php
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
return view('welcome');
});
Route::get('/tentang-kami', function () {
return 'Ini adalah halaman tentang kami.';
});Diagram Alur
Browser: GET /tentang-kami
│
▼
routes/web.php
│
▼
Closure Dieksekusi ──> Return: "Ini adalah halaman tentang kami."Hafalan:
Route::get('url', handler) → tangani request GET pada URL tertentu7. 🟢 HTTP Routing Methods
Konsep
Laravel mendukung seluruh kata kerja metode standar HTTP (RESTful verbs).
Contoh Method Routing
use Illuminate\Support\Facades\Route;
// Method Standar
Route::get('/users', [UserController::class, 'index']);
Route::post('/users', [UserController::class, 'store']);
Route::put('/users/{id}', [UserController::class, 'update']);
Route::patch('/users/{id}', [UserController::class, 'updatePartial']);
Route::delete('/users/{id}', [UserController::class, 'destroy']);
// Menerima beberapa method tertentu
Route::match(['get', 'post'], '/feedback', [FeedbackController::class, 'handle']);
// Menerima seluruh method HTTP apa saja
Route::any('/webhook', [WebhookController::class, 'handle']);Hafalan:
GET → membaca / mengambil data
POST → membuat / mengirim data baru
PUT → mengganti seluruh data
PATCH → memperbarui sebagian data
DELETE → menghapus data8. 🟢 View & Blade Templating Dasar
Konsep
Blade adalah template engine bawaan Laravel yang sangat cepat dan berekstensi .blade.php.
1. Membuat View (resources/views/greeting.blade.php)
<!DOCTYPE html>
<html lang="id">
<head>
<title>Greeting</title>
</head>
<body>
<!-- Output data dengan proteksi XSS otomatis (htmlspecialchars) -->
<h1>Halo, {{ $name }}!</h1>
<!-- Kondisional -->
@if ($age >= 18)
<p>Status: Dewasa ({{ $age }} tahun)</p>
@else
<p>Status: Di bawah umur</p>
@endif
<!-- Perulangan -->
<h3>Daftar Hobi:</h3>
<ul>
@forelse ($hobbies as $hobby)
<li>{{ $hobby }}</li>
@empty
<li>Belum ada hobi yang terdaftar.</li>
@endforelse
</ul>
</body>
</html>2. Mengembalikan View dari Route / Controller
Route::get('/greeting', function () {
return view('greeting', [
'name' => 'Budi',
'age' => 20,
'hobbies' => ['Membaca', 'Coding', 'Bermusik'],
]);
});Hafalan:
{{ $var }} → cetak variabel aman (escaped HTML)
{!! $var !!} → cetak variabel mentah (raw HTML - hati-hati XSS!)
@if / @endif → kondisional
@foreach → looping data9. 🟢 Layout Blade & Asset Vite
Konsep
Agar tidak menulis struktur HTML (<html>, <head>, <nav>) berulang kali di setiap halaman, gunakan pola Blade Layout Inheritance.
1. Master Layout (resources/views/layouts/app.blade.php)
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<title>@yield('title', 'Aplikasi Laravel')</title>
<!-- Memuat asset via Vite -->
@vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
<body>
<nav class="navbar">
<a href="/">Beranda</a>
<a href="/about">Tentang</a>
</nav>
<main class="container">
<!-- Tempat konten halaman anak disisipkan -->
@yield('content')
</main>
</body>
</html>2. Halaman Anak (resources/views/about.blade.php)
@extends('layouts.app')
@section('title', 'Tentang Kami')
@section('content')
<h1>Halaman Tentang Kami</h1>
<p>Selamat datang di profil perusahaan kami.</p>
@endsectionDiagram Alur Layout
Master Layout (app.blade.php)
│
│ @yield('content')
▼
Child View (about.blade.php) disisipkan
│
▼
HTML Utuh Dikirim ke BrowserHafalan:
@extends('layouts.app') → warisi layout induk
@section('content') → isi slot konten
@yield('content') → titik penyisipan konten di layout induk10. 🟢 Route Parameters
Konsep
Bagian URL yang dinamis didefinisikan menggunakan kurung kurawal {param}.
1. Required Parameter
Route::get('/users/{id}', function (string $id) {
return "Profil Pengguna ID: {$id}";
});2. Multiple Parameters
Route::get('/posts/{postId}/comments/{commentId}', function (string $postId, string $commentId) {
return "Post {$postId} - Komentar {$commentId}";
});3. Optional Parameter ({param?})
Route::get('/users/{name?}', function (?string $name = 'Tamu') {
return "Halo, {$name}";
});4. Parameter Constraints (Validasi Regex)
Gunakan where untuk membatasi format parameter:
// Hanya cocok jika {id} berupa angka
Route::get('/products/{id}', function (string $id) {
return "Produk ID: {$id}";
})->where('id', '[0-9]+');
// Menggunakan helper bawaan
Route::get('/users/{id}', function (string $id) { ... })->whereNumber('id');
Route::get('/category/{slug}', function (string $slug) { ... })->whereAlphaNumeric('slug');Hafalan:
{id} → parameter wajib
{name?} → parameter opsional
->whereNumber('id') → wajib angka11. 🟢 Named Routes & URL Generator
Konsep
Memberikan nama unik pada rute menggunakan ->name() mempermudah pembuatan URL dan redirect tanpa terikat pada hardcoded string.
Definisi Named Route
Route::get('/pengguna/profil/akun/{id}', [UserProfileController::class, 'show'])->name('profile.show');Membuat URL dari Nama Rute
Di Controller / PHP:
// Menghasilkan: http://127.0.0.1:8000/pengguna/profil/akun/42
$url = route('profile.show', ['id' => 42]);
// Redirect langsung ke named route
return redirect()->route('profile.show', ['id' => 42]);Di Blade View:
<a href="{{ route('profile.show', ['id' => 42]) }}">Lihat Profil</a>Hafalan:
->name('nama.rute') ──> route('nama.rute', ['id' => 1])12. 🟢 Controller
Konsep
Controller bertugas mengelompokkan logika penanganan HTTP request yang berkaitan ke dalam satu class tersendiri.
1. Membuat Controller via Artisan
php artisan make:controller UserController2. Struktur Class Controller (app/Http/Controllers/UserController.php)
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\View\View;
class UserController extends Controller
{
public function index(): View
{
$users = ['Budi', 'Andi', 'Siti'];
return view('users.index', compact('users'));
}
public function show(string $id): View
{
return view('users.show', ['userId' => $id]);
}
}3. Menghubungkan Route dengan Controller
use App\Http\Controllers\UserController;
Route::get('/users', [UserController::class, 'index'])->name('users.index');
Route::get('/users/{id}', [UserController::class, 'show'])->name('users.show');Diagram Alur Request ke Controller
Browser: GET /users
│
│ routes/web.php
▼
UserController@index
│
│ ambil data & render view
▼
resources/views/users/index.blade.phpHafalan:
Route::get('/path', [NamaController::class, 'namaMethod'])13. 🟢 HTTP Request Object
Konsep
Objek Illuminate\Http\Request menyediakan representasi lengkap dari HTTP request yang masuk ke server (headers, URL, method, IP, input).
Injeksi Request ke Controller Method
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class ContactController extends Controller
{
public function submit(Request $request)
{
// Membaca method HTTP (GET / POST)
$method = $request->method();
// Membaca path rute aktif
$path = $request->path(); // e.g. 'contact/submit'
// Membaca full URL
$url = $request->fullUrl();
// Membaca IP client
$ip = $request->ip();
// Memeriksa header request
$userAgent = $request->header('User-Agent');
}
}Hafalan:
Request $request → otomatis diinjeksi ke controller method oleh service container14. 🟢 Mengambil Data Input Request
Konsep
Laravel menyediakan beragam helper untuk membaca input form maupun query string secara aman.
Berbagai Cara Mengambil Input
use Illuminate\Http\Request;
public function store(Request $request)
{
// 1. Mengambil 1 input spesifik (dengan default value jika kosong)
$name = $request->input('name', 'Anonim');
// 2. Mengambil via dynamic property
$email = $request->email;
// 3. Mengambil SEMUA input sekaligus (Array associative)
$allData = $request->all();
// 4. Mengambil HANYA field tertentu (White-listing)
$safeData = $request->only(['name', 'email']);
// 5. Mengambil semua KECUALI field tertentu
$data = $request->except(['password_confirmation']);
// 6. Mengambil nilai boolean (otomatis konversi "1", "true", "on" -> true)
$subscribe = $request->boolean('newsletter');
// 7. Memeriksa keberadaan input
if ($request->has('promo_code')) {
// field ada di request
}
if ($request->filled('promo_code')) {
// field ada dan nilainya TIDAK kosong
}
}Hafalan:
$request->input('field') → ambil 1 nilai
$request->only(['field1', 'field2']) → ambil whitelist field
$request->filled('field') → cek jika ada dan tidak kosong15. 🟢 Form Validation Dasar
Konsep
Validasi memastikan seluruh data yang dikirimkan user memenuhi aturan tipe, ukuran, dan format sebelum diproses oleh database.
Contoh Validasi di Controller
use Illuminate\Http\Request;
public function store(Request $request)
{
// Otomatis redirect kembali jika validasi gagal, atau melempar JSON error jika API
$validated = $request->validate([
'name' => ['required', 'string', 'min:3', 'max:50'],
'email' => ['required', 'email', 'max:100'],
'age' => ['required', 'integer', 'min:17'],
'password' => ['required', 'string', 'min:8'],
]);
// $validated hanya berisi data yang lolos validasi
return "User {$validated['name']} berhasil divalidasi!";
}Menampilkan Error di Blade View (create.blade.php)
<!-- Menampilkan semua error di bagian atas jika ada -->
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<form action="/users" method="POST">
@csrf
<div>
<label>Nama:</label>
<input type="text" name="name" value="{{ old('name') }}">
<!-- Error spesifik field name -->
@error('name')
<span class="text-danger">{{ $message }}</span>
@enderror
</div>
<button type="submit">Daftar</button>
</form>Diagram Alur Validasi
User Submit Form
│
│ $request->validate()
▼
Pengecekan Aturan Validasi
│ │
│ Lolos │ Gagal
▼ ▼
Lanjut ke Logika Redirect Back + Input Lama (old()) + Error MessagesHafalan:
$request->validate([...]) ──> validasi input
{{ old('name') }} ──> kembalikan input user saat validasi gagal
@error('field') ──> tampilkan pesan error spesifik16. 🟢 Form Request Validation
Konsep
Untuk menjaga Controller tetap ramping (Skinny Controller), aturan validasi yang panjang atau kompleks sebaiknya dipindahkan ke class Form Request.
1. Membuat Form Request
php artisan make:request StoreUserRequest2. Mengisi Aturan di app/Http/Requests/StoreUserRequest.php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class StoreUserRequest extends FormRequest
{
public function authorize(): bool
{
return true; // Set true agar diizinkan
}
public function rules(): array
{
return [
'name' => ['required', 'string', 'max:50'],
'email' => ['required', 'email', 'unique:users,email'],
];
}
}3. Injeksi ke Controller Method
use App\Http\Requests\StoreUserRequest;
public function store(StoreUserRequest $request)
{
// Validasi sudah otomatis berjalan SEBELUM baris ini dieksekusi!
$validated = $request->validated();
// Simpan ke database...
}Hafalan:
php artisan make:request → buat class validasi terpisah
$request->validated() → ambil data hasil validasi Form Request17. 🟢 HTTP Responses
Konsep
Laravel mendukung beragam jenis response: string, Blade view, JSON data, download file, dan kustom status code.
Ragam Response
use Illuminate\Http\Response;
use Illuminate\Http\JsonResponse;
// 1. Plain String Response
return response('Data berhasil disimpan', 200);
// 2. Custom Status Code & Header
return response('Akses Ditolak', 403)->header('X-Custom-Header', 'Value');
// 3. JSON Response (REST API)
return response()->json([
'success' => true,
'data' => ['id' => 1, 'name' => 'Budi'],
], 200);
// 4. File Download (Mengunduh file ke komputer user)
return response()->download(storage_path('app/public/laporan.pdf'), 'laporan-tahunan.pdf');
// 5. File Inline (Menampilkan gambar/PDF langsung di browser)
return response()->file(storage_path('app/public/gambar.jpg'));Hafalan:
response()->json() → kirim data JSON (API)
response()->download() → unduh file
response('Text', 201) → kirim status code HTTP kustom18. 🟢 HTTP Redirects
Konsep
Redirect menginstruksikan browser untuk berpindah ke URL lain setelah suatu aksi selesai diproses (misal: setelah berhasil menyimpan data form).
Ragam Sintaks Redirect
// 1. Redirect ke URL path tertentu
return redirect('/dashboard');
// 2. Redirect ke Named Route
return redirect()->route('users.index');
// 3. Redirect ke Named Route beserta Parameter
return redirect()->route('users.show', ['id' => 10]);
// 4. Redirect kembali ke halaman sebelumnya
return redirect()->back();
// 5. Redirect kembali dengan input lama yang dipertahankan
return back()->withInput();
// 6. Redirect dengan pesan flash data
return redirect()->route('users.index')->with('success', 'User berhasil ditambahkan!');Hafalan:
redirect()->route('name') → redirect ke named route
redirect()->back() → kembali ke halaman sebelumnya
->with('key', 'message') → sertakan flash message19. 🟢 Session & Flash Data
Konsep
HTTP bersifat stateless. Session digunakan untuk menyimpan data pengguna lintas request (seperti user login atau keranjang belanja).
Mengelola Session
use Illuminate\Http\Request;
// 1. Menyimpan data ke Session
session(['theme' => 'dark']);
$request->session()->put('cart_total', 150000);
// 2. Membaca data Session
$theme = session('theme', 'light'); // dengan default value 'light'
$cart = $request->session()->get('cart_total');
// 3. Memeriksa keberadaan data Session
if ($request->session()->has('theme')) { ... }
// 4. Menghapus data Session
$request->session()->forget('theme');
$request->session()->flush(); // Hapus seluruh isi session
// 5. Flash Data (Hanya bertahan selama 1 request berikutnya, cocok untuk notifikasi sukses)
$request->session()->flash('status', 'Profil berhasil diperbarui!');Membaca Flash Message di Blade
@if (session('status'))
<div class="alert alert-success">
{{ session('status') }}
</div>
@endifHafalan:
session(['key' => 'value']) → simpan permanen di sesi
session()->flash('key', 'message') → simpan sementara untuk 1 request berikutnya20. 🟢 Cookies
Konsep
Cookie adalah potongan data kecil yang disimpan di browser client dan otomatis dikirimkan kembali ke server pada setiap request berikutnya.
Membaca dan Menulis Cookie
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cookie;
// 1. Membaca Cookie dari Request
public function index(Request $request)
{
$fontSize = $request->cookie('font_size', '14px');
// atau via Facade:
$theme = Cookie::get('theme', 'light');
}
// 2. Menempelkan Cookie ke Response (nama, nilai, menit kedaluwarsa)
public function setCookie()
{
return response('Cookie berhasil disimpan')
->cookie('font_size', '16px', 60 * 24 * 7); // bertahan 7 hari
}
// 3. Menghapus Cookie
public function deleteCookie()
{
return response('Cookie dihapus')->withoutCookie('font_size');
}Catatan: Secara default, seluruh cookie di Laravel otomatis dienkripsi dan ditandatangani (signed) demi keamanan agar tidak bisa diubah oleh client.
Hafalan:
$request->cookie('name') → baca cookie
response()->cookie('name', 'value', $minutes) → kirim cookie ke browser21. 🟢 Middleware Dasar
Konsep
Middleware bertindak sebagai penyaring (filter/pipeline) HTTP request yang masuk sebelum mencapai Controller, atau memeriksa response sebelum dikirim ke browser.
1. Membuat Middleware via Artisan
php artisan make:middleware EnsureTokenIsValid2. Struktur Middleware (app/Http/Middleware/EnsureTokenIsValid.php)
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class EnsureTokenIsValid
{
public function handle(Request $request, Closure $next): Response
{
// 1. Logika SEBELUM Controller dieksekusi
if ($request->input('token') !== 'secret-token-123') {
return redirect('/login')->with('error', 'Token akses tidak valid.');
}
// 2. Teruskan request ke lapisan berikutnya (Controller)
$response = $next($request);
// 3. Logika SETELAH Controller dieksekusi (opsional)
return $response;
}
}Diagram Pipeline Middleware
HTTP Request Masuk
│
▼
[ Middleware 1: EncryptCookies ]
│
▼
[ Middleware 2: VerifyCsrfToken ]
│
▼
[ Middleware 3: Custom Auth Middleware ]
│ │
│ Token Valid │ Token Tidak Valid
▼ ▼
Controller Action Redirect / Response ErrorHafalan:
return $next($request); ──> izinkan request lanjut ke controller22. 🟢 Mendaftarkan Middleware
Konsep
Pada Laravel modern (Laravel 11 / 12), middleware didaftarkan secara elegan melalui file bootstrap/app.php (menggantikan file Kernel.php lama).
Konfigurasi di bootstrap/app.php
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Middleware;
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__.'/../routes/web.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
)
->withMiddleware(function (Middleware $middleware) {
// 1. Mendaftarkan Alias Middleware (untuk digunakan di routes)
$middleware->alias([
'is-admin' => \App\Http\Middleware\EnsureUserIsAdmin::class,
'check-token' => \App\Http\Middleware\EnsureTokenIsValid::class,
]);
// 2. Menambahkan Global Middleware (berjalan di SEMUA request)
// $middleware->append(\App\Http\Middleware\LogActivity::class);
})
->create();Memasang Middleware pada Rute (routes/web.php)
Route::get('/admin/dashboard', [AdminController::class, 'index'])
->middleware('is-admin');Hafalan:
bootstrap/app.php ->withMiddleware() ──> daftarkan alias middleware
->middleware('alias') ──> pasang ke route23. 🟢 CSRF Protection
Konsep
CSRF (Cross-Site Request Forgery) adalah serangan di mana situs jahat mengeksekusi aksi berbahaya atas nama pengguna yang sedang terautentikasi. Laravel otomatis melindungi seluruh request POST, PUT, PATCH, dan DELETE dengan token CSRF.
1. Menyertakan CSRF Token di Form Blade
Setiap form HTML dengan method pengubah state wajib menyertakan @csrf:
<form action="/users" method="POST">
@csrf <!-- Menghasilkan input hidden berisi token CSRF -->
<input type="text" name="name">
<button type="submit">Simpan</button>
</form>2. Form Method Spoofing (@method)
Karena tag HTML <form> hanya mendukung method GET dan POST, gunakan direktif @method untuk mensimulasikan method PUT atau DELETE:
<form action="/users/1" method="POST">
@csrf
@method('PUT') <!-- Mensimulasikan request PUT -->
<input type="text" name="name" value="Budi Baru">
<button type="submit">Update</button>
</form>Hafalan:
@csrf → wajib di setiap form POST/PUT/DELETE
@method('PUT') → spoofing HTTP method PUT / DELETEKesalahan Umum:
❌ Lupa menulis @csrf pada form HTML.
Akibat: Laravel akan melempar error 419 Page Expired.
24. 🟢 Route Groups & Prefixes
Konsep
Route Groups memungkinkan kita berbagi atribut rute (seperti middleware, prefix URL, atau namespace nama rute) ke banyak rute sekaligus tanpa menulisnya berulang-ulang.
Contoh Route Group Lengkap
use App\Http\Controllers\Admin\DashboardController;
use App\Http\Controllers\Admin\UserController;
// Grup Admin: Prefix URL '/admin', Named Route Prefix 'admin.', dan Middleware 'is-admin'
Route::middleware(['auth', 'is-admin'])
->prefix('admin')
->name('admin.')
->group(function () {
// URL: /admin/dashboard | Name: admin.dashboard
Route::get('/dashboard', [DashboardController::class, 'index'])->name('dashboard');
// URL: /admin/users | Name: admin.users
Route::get('/users', [UserController::class, 'index'])->name('users');
});Grouping Berdasarkan Controller
Route::controller(OrderController::class)->group(function () {
Route::get('/orders', 'index');
Route::get('/orders/{id}', 'show');
Route::post('/orders', 'store');
});Hafalan:
Route::prefix('admin')->group(...) ──> grup URL /admin/...
Route::name('admin.')->group(...) ──> grup nama rute admin....25. 🟢 File Storage Disk
Konsep
Laravel menyediakan abstraksi filesystem yang fleksibel (Illuminate\Support\Facades\Storage) untuk mengelola file lokal maupun cloud (Amazon S3) dengan sintaks yang sama.
Konfigurasi Disk (config/filesystems.php)
local: File disimpan distorage/app/private(tidak bisa diakses publik browser).public: File disimpan distorage/app/public(bisa diakses publik setelah membuat symbolic link).
Perintah Symbolic Link
Agar file di disk public dapat diakses langsung oleh browser:
php artisan storage:linkPerintah ini membuat shortcut dari public/storage mengarah ke storage/app/public.
Mengelola File dengan Facade Storage
use Illuminate\Support\Facades\Storage;
// Menulis file
Storage::disk('public')->put('catatan.txt', 'Isi teks catatan');
// Membaca file
$content = Storage::disk('public')->get('catatan.txt');
// Memeriksa keberadaan file
if (Storage::disk('public')->exists('catatan.txt')) { ... }
// Menghapus file
Storage::disk('public')->delete('catatan.txt');
// Mendapatkan URL publik file
$url = Storage::url('catatan.txt'); // e.g. /storage/catatan.txtHafalan:
php artisan storage:link ──> hubungkan storage publik ke folder public/
Storage::disk('public')->put() ──> simpan file26. 🟢 File Upload Handling
Konsep
Laravel mempermudah validasi dan penyimpanan file yang diunggah (file upload) oleh pengguna.
1. Form Upload di Blade
Pastikan form memiliki atribut enctype="multipart/form-data":
<form action="/upload-avatar" method="POST" enctype="multipart/form-data">
@csrf
<input type="file" name="avatar">
<button type="submit">Upload Foto</button>
</form>2. Memproses Upload di Controller
use Illuminate\Http\Request;
public function upload(Request $request)
{
// Validasi file (gambar max 2MB)
$request->validate([
'avatar' => ['required', 'file', 'image', 'max:2048'], // max dalam kilobyte (2048 KB = 2MB)
]);
if ($request->hasFile('avatar') && $request->file('avatar')->isValid()) {
// Simpan otomatis ke folder storage/app/public/avatars dengan nama unik
$path = $request->file('avatar')->store('avatars', 'public');
return "File berhasil disimpan di: {$path}";
}
return "Upload gagal.";
}Hafalan:
enctype="multipart/form-data" ──> wajib pada form upload
$request->file('avatar')->store('folder', 'public') ──> simpan file aman27. 🟢 Error Handling & Custom Error Pages
Konsep
Laravel otomatis menangani exception dan menampilkan halaman error detail saat development (APP_DEBUG=true). Di server production (APP_DEBUG=false), Laravel menampilkan halaman error HTTP yang ramah.
Membuat Custom Error Page
Cukup buat file Blade di dalam folder resources/views/errors/ sesuai kode status HTTP:
resources/views/errors/
├── 404.blade.php <── Ditampilkan saat halaman tidak ditemukan
├── 403.blade.php <── Ditampilkan saat akses dilarang (Forbidden)
└── 500.blade.php <── Ditampilkan saat terjadi server internal errorContoh resources/views/errors/404.blade.php:
<!DOCTYPE html>
<html lang="id">
<head>
<title>404 - Halaman Tidak Ditemukan</title>
</head>
<body style="text-align: center; padding-top: 5rem;">
<h1>404</h1>
<p>Maaf, halaman yang Anda tuju tidak ditemukan.</p>
<a href="/">Kembali ke Beranda</a>
</body>
</html>Hafalan:
resources/views/errors/404.blade.php ──> kustomisasi tampilan error 40428. 🟢 HTTP Exceptions
Konsep
Fungsi helper abort() digunakan untuk langsung menghentikan eksekusi kode dan melempar HTTP exception dengan kode status tertentu.
Penggunaan abort()
public function show(string $id)
{
$user = findUserById($id);
// 1. Melempar error 404 jika user tidak ditemukan
if (!$user) {
abort(404, 'Pengguna tidak ditemukan.');
}
// 2. Helper kondisional abort_if()
abort_if($user->is_banned, 403, 'Akun Anda sedang dibekukan.');
// 3. Helper kondisional abort_unless()
abort_unless($user->is_active, 403, 'Akun belum diaktivasi.');
return view('users.show', compact('user'));
}Hafalan:
abort(404) → hentikan & lempar 404 Not Found
abort(403) → hentikan & lempar 403 Forbidden
abort_if(condition) → abort jika condition bernilai true29. 🟢 Testing Dasar
Konsep
Laravel dirancang dengan dukungan testing bawaan menggunakan PHPUnit atau Pest. Testing memastikan aplikasi berfungsi dengan benar setelah ada perubahan kode.
1. Membuat Feature Test
php artisan make:test UserPageTest2. Menulis Test (tests/Feature/UserPageTest.php)
namespace Tests\Feature;
use Tests\TestCase;
class UserPageTest extends TestCase
{
public function test_halaman_beranda_bisa_diakses(): void
{
// 1. Simulasikan HTTP GET request
$response = $this->get('/');
// 2. Asersi status response harus 200 OK
$response->assertStatus(200);
// 3. Asersi teks tertentu tampil di halaman
$response->assertSee('Selamat Datang');
}
public function test_form_user_butuh_nama(): void
{
// Simulasikan POST tanpa data
$response = $this->post('/users', []);
// Asersi terjadi error validasi pada session
$response->assertSessionHasErrors(['name']);
}
}3. Menjalankan Test
php artisan testHafalan:
php artisan test ──> jalankan seluruh test otomatis aplikasi30. 🟢 Environment Configuration (.env)
Konsep
File .env di root project menyimpan variabel konfigurasi lingkungan lokal yang berbeda-beda di setiap komputer pengembang atau server (seperti koneksi database dan kredensial API).
Contoh File .env
APP_NAME=LaravelApp
APP_ENV=local
APP_KEY=base64:randomKeyGeneratedByArtisan=
APP_DEBUG=true
APP_URL=http://localhost:8000
DB_CONNECTION=sqliteMembaca Nilai .env via env()
// env('KEY', 'DEFAULT_FALLBACK')
$appName = env('APP_NAME', 'DefaultApp');Penting: Jangan pernah memanggil fungsi env() langsung di dalam kode Controller atau Blade. Panggil env() hanya di dalam file-file folder config/, lalu baca menggunakan fungsi config().
Hafalan:
.env → file rahasia lokal (jangan pernah di-commit ke Git!)
.env.example → template contoh konfigurasi untuk tim31. 🟢 Application Environment & Debug Mode
Konsep
Dua variabel terpenting di dalam .env:
APP_ENV: Menentukan lingkungan kerja (local,staging,production).APP_DEBUG: Menentukan apakah pesan error detail ditampilkan atau disembunyikan.
Panduan Pengaturan Environment
Komputer Pengembang (Lokal):
APP_ENV=local
APP_DEBUG=true <── Error detail tampil untuk mempermudah debugging
Server Live (Produksi):
APP_ENV=production
APP_DEBUG=false <── WAJIB false agar kredensial/database tidak bocor ke publik!Memeriksa Status Environment di Kode
use Illuminate\Support\Facades\App;
if (App::environment('local')) {
// Kode khusus lokal
}
if (App::environment(['staging', 'production'])) {
// Kode khusus server
}Hafalan:
APP_DEBUG=false ──> WAJIB di server production demi keamanan!32. 🟢 File Konfigurasi Laravel
Konsep
Seluruh setting resmi aplikasi tersimpan di dalam direktori config/ (seperti config/app.php, config/database.php, config/filesystems.php).
Membaca Nilai Konfigurasi dengan config()
Gunakan notasi titik (dot notation) nama_file.nama_kunci:
// Membaca 'name' dari config/app.php
$appName = config('app.name');
// Membaca dengan default fallback
$timezone = config('app.timezone', 'UTC');
// Mengubah konfigurasi saat runtime (hanya untuk request saat ini)
config(['app.locale' => 'id']);Mengapa config() > env()?
Ketika konfigurasi di-cache di server production (php artisan config:cache), seluruh pemanggilan env() di luar file config/ akan mengembalikan null!
.env ──(dibaca oleh)──> config/app.php ──(dibaca oleh)──> config('app.name')Hafalan:
config('file.key') ──> cara standar & aman membaca konfigurasi aplikasi33. 🟢 Configuration Caching
Konsep
Di server production, menggabungkan seluruh file konfigurasi menjadi satu file cache meningkatkan performa boot Laravel secara signifikan.
Perintah Artisan Config Cache
# Membuat cache konfigurasi (jalankan di server production saat deploy)
php artisan config:cache
# Menghapus cache konfigurasi (jika ada perubahan file .env / config)
php artisan config:clear
# Membersihkan seluruh cache (config, route, view)
php artisan optimize:clearHafalan:
php artisan config:cache → aktifkan cache konfigurasi (production)
php artisan config:clear → bersihkan cache konfigurasi34. 🟡 Dependency Injection
Konsep
Dependency Injection (DI) adalah teknik di mana sebuah class tidak membuat objek dependensinya sendiri secara manual (new Service()), melainkan “disuntikkan” (injected) dari luar melalui constructor atau method parameter.
Contoh Constructor Injection
namespace App\Http\Controllers;
use App\Services\PaymentGateway;
use Illuminate\Http\Request;
class CheckoutController extends Controller
{
// PaymentGateway otomatis disuntikkan oleh Laravel
public function __construct(
protected PaymentGateway $payment
) {}
public function process(Request $request)
{
$this->payment->charge($request->input('amount'));
return 'Pembayaran sukses.';
}
}Diagram Alur Dependency Injection
Request Masuk ke CheckoutController
│
▼
Laravel Service Container Mendeteksi:
"CheckoutController butuh PaymentGateway"
│
│ Container otomatis membuat new PaymentGateway()
▼
Injeksi Objek ke Constructor ControllerHafalan:
Type-hint class pada constructor/method ──> Laravel sediakan objeknya otomatis35. 🟡 Service Container
Konsep
Service Container adalah kotak peralatan (IoC Container) milik Laravel yang bertugas mengelola pembuatan objek (instantiation) dan menyelesaikan dependensi class secara otomatis.
1. Binding (Mendaftarkan Pembuatan Objek)
// Bind biasa (Instance baru dibuat setiap kali dipanggil)
app()->bind(BillingService::class, function ($app) {
return new BillingService(config('services.stripe.key'));
});
// Singleton (Hanya 1 instance dibuat & dipakai bersama di seluruh aplikasi)
app()->singleton(ReportGenerator::class, function ($app) {
return new ReportGenerator();
});2. Resolving (Mengambil Objek dari Container)
// Mengambil objek yang sudah siap pakai beserta dependensinya
$billing = app(BillingService::class);Hafalan:
app()->bind() → buat objek baru tiap diminta
app()->singleton() → gunakan objek tunggal yang sama selamanya
app(NamaClass::class) → ambil instance dari container36. 🟡 Service Providers
Konsep
Service Providers adalah tempat sentral untuk mendaftarkan (register) binding Service Container dan menginisialisasi (boot) konfigurasi paket/service.
Struktur Service Provider (app/Providers/AppServiceProvider.php)
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\Services\PaymentService;
class AppServiceProvider extends ServiceProvider
{
// 1. Method register: HANYA untuk binding ke Service Container
public function register(): void
{
$this->app->singleton(PaymentService::class, function ($app) {
return new PaymentService();
});
}
// 2. Method boot: Dipanggil setelah SEMUA service provider selesai di-register
public function boot(): void
{
// Tempat setting global (misal Blade directives, model events, paginator style)
}
}Hafalan:
register() → tempat mendaftarkan binding ke container
boot() → tempat menjalankan aksi setelah semua provider terdaftar37. 🟡 Facades
Konsep
Facades menyediakan antarmuka statis (static proxy) yang mudah dibaca ke class-class yang tersimpan di dalam Service Container.
Contoh Facade vs Underlying Service
// Menggunakan Facade statis
use Illuminate\Support\Facades\Cache;
Cache::put('key', 'value', 600);
$val = Cache::get('key');Di balik layar, Cache::get() diteruskan ke objek sebenarnya di dalam Service Container:
Cache::get('key')
│
│ diterjemahkan oleh Facade
▼
app('cache')->get('key')Daftar Facade yang Sering Digunakan
Route::... ──> Mengatur rute aplikasi
Storage::... ──> Mengelola file storage
Session::... ──> Mengelola session
Cookie::... ──> Mengelola cookies
Crypt::... ──> Enkripsi & dekripsi data
Hash::... ──> Password hashing
Log::... ──> Menulis log error/infoHafalan:
Facade = sintaks statis ringkas untuk mengakses service di Service Container38. 🟡 Encryption vs Hashing
Konsep
- Encryption (Dua Arah): Data diacak menjadi ciphertext dan dapat dikembalikan (didekripsi) ke bentuk aslinya menggunakan APP_KEY.
- Hashing (Satu Arah): Data diubah menjadi hash matematis dan tidak bisa dikembalikan. Digunakan khusus untuk password.
1. Encryption (Data Sensitif Rahasia)
use Illuminate\Support\Facades\Crypt;
// Mengenkripsi string
$encrypted = Crypt::encryptString('Data Rahasia NIK');
// Mendekripsi string
$original = Crypt::decryptString($encrypted);2. Hashing (Password User)
use Illuminate\Support\Facades\Hash;
// Membuat hash password
$hashedPassword = Hash::make('password123');
// Memeriksa kecocokan password input dengan hash di database
if (Hash::check('password123', $hashedPassword)) {
// Password benar
}Hafalan:
Crypt::encryptString() → untuk data rahasia yang butuh dibaca lagi
Hash::make() → khusus password (satu arah, tidak bisa didekripsi)39. 🔴 Maintenance Mode
Konsep
Saat melakukan pembaruan besar di server produksi, Anda dapat mengaktifkan Maintenance Mode agar pengguna menerima halaman informasi ramah (HTTP status 503) alih-alih error aplikasi.
Perintah Maintenance Mode
# Aktifkan maintenance mode
php artisan down
# Aktifkan dengan status code 503
php artisan down --status=503
# Aktifkan dengan Secret Bypass (akses via token rahasia)
php artisan down --secret="akses-rahasia-admin"
# Matikan maintenance mode (kembali online)
php artisan upJika secret bypass aktif, akses URL: https://example.com/akses-rahasia-admin sekali untuk mendapatkan cookie bypass dan melihat situs seperti biasa.
Hafalan:
php artisan down → aplikasi maintenance (503)
php artisan up → aplikasi normal online kembali40. 🧠 Peta Ingatan Cepat
A. Alur Lengkap HTTP Request-Response
Browser: HTTP Request
│
▼
routes/web.php
│
▼
Middleware Pipeline (CSRF, Auth, Session)
│
▼
Controller (Method Action)
│
▼
Request Validation ($request->validate())
│
▼
Business Logic / Model Data
│
▼
HTTP Response (Blade View / JSON / Redirect)
│
▼
Browser: Render HTML / JSONB. Anatomi Route
Route::get('/users/{id}', [UserController::class, 'show'])
│ │ │ │
│ │ │ └── Action Method
│ │ └──────────────────── Controller Class
│ └──────────────────────────────────── URI Pattern
└─────────────────────────────────────────────── HTTP VerbC. Alur Form Submission & Validasi
Blade Form (@csrf) ──(POST)──> Route ──> Controller@store
│
│ $request->validate()
┌──────────────┴──────────────┐
│ Lolos │ Gagal
▼ ▼
Proses Database Redirect Back (old())
│ │
▼ ▼
Redirect + with('success') Tampilkan $errors41. 📚 Tabel Ringkasan
| Materi | Konsep / API Utama | Fungsi & Kegunaan |
|---|---|---|
| Instalasi | composer create-project | Membuat project baru Laravel |
| Server | php artisan serve | Menjalankan local development server |
| Route | Route::get(), post() | Menghubungkan URL ke Controller/Closure |
| Named Route | ->name('nama'), route() | Identitas rute untuk pembuatan URL fleksibel |
| Controller | make:controller | Class pemisah logika penanganan HTTP |
| View | view('nama', $data) | Merender template antarmuka Blade |
| Request Input | $request->input(), only() | Membaca parameter data dari client |
| Validation | $request->validate() | Memvalidasi integritas input form |
| Form Request | make:request | Class terisolasi untuk aturan validasi kompleks |
| Response | response(), json() | Mengembalikan data teks, status code, atau JSON |
| Redirect | redirect()->route() | Mengarahkan browser ke URL lain |
| Session | session(), ->with() | Menyimpan data persist sementara antar-request |
| Cookie | cookie(), $request->cookie | Mengelola data cookie pada browser |
| Middleware | make:middleware, $next | Menyaring dan mengamankan HTTP request |
| CSRF | @csrf | Token pelindung serangan Cross-Site Request Forgery |
| Storage | Storage::disk(), storage:link | Abstraksi penyimpanan berkas/file |
| Upload | $request->file()->store() | Memvalidasi dan menyimpan upload file |
| Exception | abort(404), abort(403) | Menghentikan kode dengan HTTP error status |
| Config | config('file.key') | Membaca konfigurasi aplikasi secara aman |
| DI | Type-hinting constructor | Injeksi dependensi otomatis oleh container |
| Facades | Route, Storage, Crypt | Antarmuka statis ke service di container |
| Maintenance | artisan down, up | Mengaktifkan/mematikan maintenance mode |
42. ⚡ Cheat Code Laravel Dasar 10 Detik
php artisan serve → Jalankan server lokal
routes/web.php → Tempat daftarkan rute
view('nama', compact('x')) → Render Blade view
$request->validate([...]) → Validasi input
return redirect()->route() → Pindah halaman
@csrf → Wajib di setiap form POST
php artisan make:... → Generator otomatis class
config('app.name') → Baca setting konfigurasiContekan Alur CRUD 1 File:
// routes/web.php
Route::get('/users/create', [UserController::class, 'create'])->name('users.create');
Route::post('/users', [UserController::class, 'store'])->name('users.store');
// UserController.php
public function store(Request $request) {
$data = $request->validate([
'name' => ['required', 'string', 'max:50'],
'email' => ['required', 'email'],
]);
// Simpan data...
return redirect()->route('users.create')->with('success', 'User berhasil dibuat!');
}43. 🧭 Urutan Belajar yang Disarankan
1. 🟢 Fondasi Aplikasi
├─ Instalasi Laravel & memahami struktur folder
├─ Menjalankan server lokal (Artisan & Vite)
├─ Membuat Routing dasar & Parameter ({id})
└─ Membuat Blade View, Layout inheritance & Asset Vite
2. 🟢 Alur HTTP Request & Form
├─ Membuat Controller & menghubungkan ke Route
├─ Membaca Request Input ($request->input())
├─ Melakukan Form Validation ($request->validate())
├─ Proteksi Form dengan @csrf & method spoofing
└─ Mengembalikan Response, JSON, & Redirect with Flash Message
3. 🟡 Keamanan, File & Middleware
├─ Mengelola Session & Cookies
├─ Menyaring request dengan Middleware
├─ Mengelola File Storage & File Upload
├─ Menangani Error & HTTP Exceptions (abort(404))
└─ Konfigurasi Environment (.env vs config())
4. 🔴 Arsitektur Lanjutan
├─ Memahami Dependency Injection & Service Container
├─ Mengenal Service Providers & Facades
├─ Menjalankan Automated Testing dasar
└─ Mengerjakan Mini Project Terpadu44. 🏗️ Mini Project: CRUD Sederhana User Portal
Contoh proyek mini yang menggabungkan: Routing, Controller, Form Request Validation, Blade Layout, CSRF, dan Flash Session.
1. Controller (app/Http/Controllers/UserController.php)
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\View\View;
use Illuminate\Http\RedirectResponse;
class UserController extends Controller
{
public function create(): View
{
return view('users.create');
}
public function store(Request $request): RedirectResponse
{
$validated = $request->validate([
'name' => ['required', 'string', 'min:3', 'max:50'],
'email' => ['required', 'email'],
]);
// Simulasi simpan data...
return redirect()
->route('users.create')
->with('success', "Pengguna {$validated['name']} berhasil didaftarkan!");
}
}2. Rute (routes/web.php)
use App\Http\Controllers\UserController;
Route::get('/users/create', [UserController::class, 'create'])->name('users.create');
Route::post('/users', [UserController::class, 'store'])->name('users.store');3. Template View (resources/views/users/create.blade.php)
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<title>Pendaftaran Pengguna</title>
<style>
body { font-family: sans-serif; max-width: 500px; margin: 2rem auto; }
.alert-success { background: #d4edda; color: #155724; padding: 0.75rem; border-radius: 4px; margin-bottom: 1rem; }
.form-group { margin-bottom: 1rem; }
label { display: block; margin-bottom: 0.25rem; }
input { width: 100%; padding: 0.5rem; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; }
.text-error { color: #dc3545; font-size: 0.875rem; }
button { background: #42b883; color: white; border: none; padding: 0.6rem 1.2rem; border-radius: 4px; cursor: pointer; }
</style>
</head>
<body>
<h2>Form Pendaftaran Pengguna</h2>
<!-- Flash Message Sukses -->
@if (session('success'))
<div class="alert-success">
{{ session('success') }}
</div>
@endif
<form action="{{ route('users.store') }}" method="POST">
@csrf
<div class="form-group">
<label>Nama Lengkap:</label>
<input type="text" name="name" value="{{ old('name') }}" placeholder="Masukkan nama...">
@error('name')
<span class="text-error">{{ $message }}</span>
@enderror
</div>
<div class="form-group">
<label>Alamat Email:</label>
<input type="email" name="email" value="{{ old('email') }}" placeholder="nama@domain.com">
@error('email')
<span class="text-error">{{ $message }}</span>
@enderror
</div>
<button type="submit">Daftarkan Pengguna</button>
</form>
</body>
</html>Output Tampilan Mini Project
Form Pendaftaran Pengguna
[ Pengguna Budi Santoso berhasil didaftarkan! ]
Nama Lengkap:
[ Budi Santoso ]
Alamat Email:
[ budi@example.com ]
[ Daftarkan Pengguna ]Diagram Alur Mini Project
GET /users/create ──> UserController@create ──> users/create.blade.php
│
│ Submit Form
▼
POST /users ──> UserController@store <── Kirim Data (@csrf)
│
│ $request->validate()
▼
Redirect Back ──> users/create.blade.php + with('success')Kunci: Alur Request → Route → Controller → Validation → Response/Redirect adalah inti 80% pekerjaan pengembangan aplikasi web dengan Laravel.