Form di dunia nyata jarang berlaku sama untuk semua pengguna. Bank hanya ditanyakan bila metode pembayaran transfer, nomor kartu hanya relevan bila membayar dengan kartu, dan daftar kontak harus divalidasi item demi item. Rules statis tidak cukup untuk kasus begini — kita butuh rules yang menyala atau padam berdasarkan isi field lain, serta kemampuan membuang field dari hasil validasi. Chapter ini mengulas perangkat validasi bersyarat Laravel: keluarga required_if, exclude_unless, rule sometimes, dan Rule::when().

Contoh penggerak kita adalah form pendaftaran dengan rules lengkap berikut:

php
$validated = $request->validate([
    'nama' => ['required', 'string'],
    'metode' => ['required', 'in:transfer,kartu'],
    'bank' => ['required_if:metode,transfer', 'string'],
    'nomor_kartu' => ['required_if:metode,kartu', 'digits:16'],
    'kode_promo' => ['required_with:nama_promo', 'string'],
    'nomor_hp' => ['required_without:telepon_rumah'],
    'telepon_rumah' => ['required_without:nomor_hp'],
    'newsletter' => ['sometimes', 'boolean'],
    'catatan' => ['exclude_unless:newsletter,1', 'nullable', 'string', 'max:100'],
    'kontak' => ['sometimes', 'array'],
    'kontak.*.nama' => ['required_with:kontak', 'string'],
    'kontak.*.email' => ['required_with:kontak', 'email'],
    'tipe' => ['required', 'string'],
    'nomor_peserta' => Rule::when(
        $request->input('tipe') === 'pelajar',
        ['required', 'digits:8'],
        ['nullable'],
    ),
]);

Keluarga required_if, required_with, required_without #

Tiga rule ini membuat field wajib berdasarkan keadaan field lain. required_if:metode,transfer berarti field wajib diisi hanya jika metode bernilai transfer. required_with:nama_promo membuat field wajib bila field lain ada isinya, dan required_without:telepon_rumah membuat field wajib bila field lain tidak ada. Kita buktikan dengan request transfer tanpa nama bank:

Output yang Dihasilkan:

text
transfer tanpa bank:
{"message":"The bank field is required when metode is transfer.","errors":{"bank":["The bank field is required when metode is transfer."]}}

Sedangkan required_without menangani ketergantungan timbal balik — nomor HP atau telepon rumah, salah satunya wajib. Saat keduanya absen, dua error muncul sekaligus:

Output yang Dihasilkan:

text
tanpa nomor_hp dan telepon_rumah:
{"message":"The nomor hp field is required when telepon rumah is not present. (and 1 more error)","errors":{"nomor_hp":["The nomor hp field is required when telepon rumah is not present."],"telepon_rumah":["The telepon rumah field is required when nomor hp is not present."]}}

Varian lanjutannya mengikuti pola yang sama: required_if_accepted:field (wajib bila field lain tercentang), required_unless:field,nilai (wajib kecuali field lain bernilai tertentu), required_with_all dan required_without_all (menuntut semua field pembanding ada/tidak ada).

exclude_unless: Membuang Field dari validated() #

Rule exclude_unless bekerja satu langkah lebih jauh dari sekadar meloloskan field: field yang di-exclude dihapus total dari hasil validated(). Pada contoh kita, catatan hanya ikut tervalidasi bila newsletter bernilai 1:

Output yang Dihasilkan:

text
tanpa newsletter, catatan dibuang:
{"nama":"Budi","metode":"transfer","bank":"BCA","nomor_hp":"08123456789","tipe":"umum"}

newsletter '1', catatan lolos:
{"nama":"Budi","metode":"transfer","bank":"BCA","nomor_hp":"08123456789","newsletter":"1","catatan":"Tolong kirim katalog.","tipe":"umum"}

Request pertama mengirim catatan berisi teks, tetapi karena newsletter tidak ada, field tersebut lenyap dari hasil — controller tidak pernah melihatnya. Saudara kandungnya exclude_if:field,nilai membuang field justru ketika kondisi terpenuhi, dan exclude_with:field membuang field bila field lain ada. Sebagai contoh, rule ['exclude_with:promo', 'string', 'max:5'] pada kode_voucher menghapus field itu seluruhnya saat promo dikirim, sehingga rule max:5 tidak lagi memeriksanya.

sometimes: Field yang Boleh Absen #

Rule sometimes berarti “validasi field ini hanya jika field tersebut ada di input”. Tanpa sometimes, rule lain seperti boolean akan tetap memeriksa field walau tidak dikirim. Pola ['sometimes', 'array'] pada kontak membuat daftar kontak sepenuhnya opsional — kosong pun lolos.

Validasi Array Bersarang dengan Asterisk #

Tanda bintang (*) di nama field memvalidasi setiap elemen array. Rule kontak.*.email memeriksa email pada semua item; error-nya bahkan menyertakan indeks elemen yang bermasalah:

Output yang Dihasilkan:

text
email kontak kedua salah:
{"message":"The kontak.1.email field must be a valid email address.","errors":{"kontak.1.email":["The kontak.1.email field must be a valid email address."]}}

semua kontak valid:
{"nama":"Budi","metode":"transfer","bank":"BCA","nomor_hp":"08123456789","tipe":"umum","kontak":[{"nama":"Siti","email":"[email protected]"},{"nama":"Rina","email":"[email protected]"}]}

Indeks kontak.1.email memberi tahu tepat item mana yang salah — sangat membantu frontend menandai baris form dinamis yang bermasalah.

Rule::when(): Dua Set Rules dalam Satu Field #

Objek Rule::when($kondisi, $rulesJikaBenar, $rulesJikaSalah) memilih rules berdasarkan kondisi runtime. Pada contoh kita, nomor_peserta wajib berisi 8 digit untuk pendaftar bertipe pelajar, tetapi menjadi opsional untuk tipe lain:

Output yang Dihasilkan:

text
pelajar tanpa nomor_peserta:
{"message":"The nomor peserta field is required.","errors":{"nomor_peserta":["The nomor peserta field is required."]}}

pelajar dengan nomor_peserta:
{"nama":"Budi","metode":"transfer","bank":"BCA","nomor_hp":"08123456789","tipe":"pelajar","nomor_peserta":"12345678"}

Argumen ketiga bersifat opsional; tanpa argumen tersebut field tidak divalidasi sama sekali saat kondisi bernilai salah.

Sebelum menutup, satu catatan tentang prepareForValidation() dari chapter sebelumnya: method tersebut juga tempat terbaik men-gabungkan nilai default bersyarat lewat $this->merge() sebelum rules dievaluasi — misalnya mengisi tipe dengan 'umum' bila pengguna tidak memilih apa pun. Validasi bersyarat kerap berpasangan dengan berkas: foto profil wajib untuk member premium, opsional untuk member biasa. Chapter berikutnya membedah validasi khusus file upload, dari mimes: sampai dimensions:. Detail lengkap selalu tersedia di dokumentasi Validation — Conditionally Adding Rules .