LaravelValidasiFormMenengah5 mnt baca

Validasi Input: Jangan Percaya User

Validasi form dengan $request->validate: required, email, unique, dan pesan custom.

Kenapa Validasi Itu Non-Negosiable

Setiap data yang masuk ke aplikasimu berasal dari pihak yang tidak bisa dipercaya: browser user, script curl, bot, atau attacker yang sengaja mengirim payload aneh. Validasi JavaScript di frontend itu cuma pemanis UX, attacker mem-bypass-nya dalam 5 detik lewat terminal. Satu-satunya garis pertahanan yang benar-benar berarti adalah validasi di server, dan Laravel membuatnya sangat murah untuk ditulis.

Validasi Inline di Controller

php
// app/Http/Controllers/PostController.php
namespace App\Http\Controllers;

use App\Models\Post;
use Illuminate\Http\Request;

class PostController extends Controller
{
    public function store(Request $request)
    {
        $validated = $request->validate([
            'title' => 'required|string|max:255',
            'body' => 'required|string|min:10',
            'email' => 'required|email|unique:users,email',
            'foto' => 'nullable|image|max:2048', // max dalam KB
        ]);

        // $validated HANYA berisi field yang lolos validasi
        Post::create($validated);

        return redirect()->route('posts.index');
    }
}

Kalau validasi gagal, Laravel otomatis redirect kembali ke halaman form dengan dua hal: session errors berisi pesan per field, dan old input supaya user tidak mengetik ulang. Kalau request-nya API (header Accept: application/json), yang dikembalikan adalah JSON 422, bukan redirect. Controller-mu tidak perlu if sama sekali.

Aturan yang Paling Sering Dipakai

Beberapa aturan yang wajib hafal di luar kepala: required (field harus ada dan tidak kosong), nullable (boleh kosong, tapi kalau diisi harus lolos aturan lain), sometimes (validasi hanya kalau field dikirim, berguna untuk PATCH), string, integer, email, confirmed (butuh field password_confirmation yang sama), exists:categories,id (foreign key harus benar-benar ada), dan unique:users,email (tidak boleh duplikat).

Jebakan paling umum ada di unique saat update data:

php
// SALAH: update profile sendiri selalu gagal karena email sendiri dianggap duplikat
'email' => 'unique:users,email',

// BENAR: kecualikan baris milik user yang sedang diupdate
use Illuminate\Validation\Rule;

'email' => Rule::unique('users', 'email')->ignore($user->id),

Tanpa ignore(), user tidak akan pernah bisa menyimpan profilnya tanpa mengganti email.

Menampilkan Error di Blade

php
{{-- resources/views/posts/create.blade.php --}}
<form method="POST" action="{{ route('posts.store') }}">
    @csrf

    <input name="title" value="{{ old('title') }}">
    @error('title')
        <p class="text-red-600">{{ $message }}</p>
    @enderror

    <textarea name="body">{{ old('body') }}</textarea>
    @error('body')
        <p class="text-red-600">{{ $message }}</p>
    @enderror

    <button type="submit">Simpan</button>
</form>

Directive @error('title') hanya render kalau ada error untuk field itu, dan $message berisi pesan errornya. Fungsi old() mengisi kembali input terakhir user. Kombinasi ini membuat form yang gagal validasi terasa sopan: error jelas per field, ketikan tidak hilang.

Pesan Error Custom

Pesan bawaan Laravel berbahasa Inggris dan kadang kaku. Kamu bisa mengganti per aturan:

php
$validated = $request->validate(
    ['title' => 'required|max:255'],
    ['title.required' => 'Judul wajib diisi ya!'],
    ['title' => 'Judul Postingan'] // nama attribute yang ramah
);

Argumen ketiga mengganti nama field di semua pesan, jadi user melihat "Judul Postingan wajib diisi" bukan "title wajib diisi". Untuk aplikasi multi-bahasa yang serius, taruh pesan di file lang/id/validation.php supaya terpusat.

Catatan teknis: Selalu validasi dari $validated atau $request->validated(), jangan dari $request->all() saat menyimpan ke database. $validated hanya berisi field yang kamu izinkan dan lolos aturan, ini mencegah attacker menyelipkan field tak terduga seperti is_admin lewat form. Validasi bukan cuma soal format benar, tapi juga soal membatasi apa yang boleh masuk.

Tantangan

Form Pendaftaran

Buat form dengan validasi: nama (required, min 3), email (required, email, unique), password (required, min 8, confirmed). Tampilkan error per field dengan @error dan isi ulang dengan old().