Laravel ile form doğrulama (validation) pratiği
Kullanıcı girdisini güvenle karşılamanın tekrar edilebilir kalıbı: Laravel doğrulama kuralları ve hata mesajları.
Her web uygulamasında kullanıcı girdisini kontrol etmek zorundasınız. Eskiden bunu her formda ayrı ayrı yapıyordum: empty(), strlen(), filter_var() kombinasyonları, elle yazılmış hata mesajları, tekrarlayan if zincirleri. İşe yarıyordu ama bakımı zorlaşıyordu ve her formda aynı kalıpları yeniden yazıyordum.
Laravel’in validation bileşeni bu süreci standart bir kalıba oturttu. Birkaç haftadır aktif projede kullanıyorum; ne kadar pratik olduğunu paylaşmak istedim.
Temel kullanım
Denetleyicide (controller) Validator sınıfını kullanıyorsunuz:
<?php
class KayitController extends BaseController
{
public function store()
{
$kurallar = [
'ad' => 'required|min:2|max:50',
'email' => 'required|email|unique:kullanicilar',
'sifre' => 'required|min:6|confirmed',
];
$dogrulayici = Validator::make(Input::all(), $kurallar);
if ($dogrulayici->fails()) {
return Redirect::back()
->withErrors($dogrulayici)
->withInput();
}
// Doğrulama geçti, kaydı oluştur
Kullanici::create(Input::only('ad', 'email', 'sifre'));
return Redirect::to('/giris')->with('mesaj', 'Kayıt başarılı.');
}
}
Validator::make() iki parametre alıyor: doğrulanacak veri ve kurallar dizisi. fails() false dönerse işleme devam ediyorsunuz.
Doğrulama kuralları
Kurallar | ile zincir halinde yazılıyor. Yaygın kullandıklarım:
| Kural | Anlamı |
|---|---|
required | Boş olamaz |
email | Geçerli e-posta formatı |
min:6 | En az 6 karakter |
max:100 | En fazla 100 karakter |
unique:tablo | Tabloda benzersiz olmalı |
confirmed | alan_confirmation alanıyla eşleşmeli |
numeric | Sayı olmalı |
in:a,b,c | Belirtilen değerlerden biri olmalı |
date | Geçerli tarih formatı |
confirmed kuralı özellikle şifre tekrarı için kullanışlı. sifre alanı için bu kuralı koyarsanız formda sifre_confirmation adında bir alan daha olmalı; ikisi eşleşmezse hata veriyor.
Hata mesajlarını görünümde göstermek
withErrors($dogrulayici) ile hatalar oturuma yazılıyor ve görünümde $errors değişkeni olarak otomatik geliyor:
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $hata)
<li>{{ $hata }}</li>
@endforeach
</ul>
</div>
@endif
<form method="POST" action="/kayit">
<div class="form-group {{ $errors->has('email') ? 'has-error' : '' }}">
<label>E-posta</label>
<input type="email" name="email" value="{{ Input::old('email') }}">
@if ($errors->has('email'))
<span class="help-block">{{ $errors->first('email') }}</span>
@endif
</div>
...
</form>
$errors->has('email') belirli bir alan için hata olup olmadığını kontrol ediyor. $errors->first('email') o alanın ilk hata mesajını veriyor. Input::old('email') ise doğrulama başarısız olduğunda kullanıcının yazdığı değeri formda geri gösteriyor; kullanıcının her şeyi tekrar yazmasını önlüyor.
Özel hata mesajları
Varsayılan İngilizce mesajlar yerine Türkçe mesaj tanımlamak için Validator::make()’e üçüncü parametre ekliyorsunuz:
$mesajlar = [
'ad.required' => 'Ad alanı zorunludur.',
'email.required' => 'E-posta alanı zorunludur.',
'email.email' => 'Geçerli bir e-posta adresi giriniz.',
'email.unique' => 'Bu e-posta adresi zaten kayıtlı.',
'sifre.min' => 'Şifre en az 6 karakter olmalıdır.',
];
$dogrulayici = Validator::make(Input::all(), $kurallar, $mesajlar);
alan.kural formatında yazıyorsunuz. Her alan ve kural kombinasyonu için ayrı mesaj tanımlanabiliyor.
Dil dosyasıyla genel çözüm
Tüm mesajları her denetleyicide tekrar yazmak yerine app/lang/tr/validation.php dosyası oluşturabilirsiniz. Laravel bu dosyayı otomatik yükler:
<?php
return [
'required' => ':attribute alanı zorunludur.',
'email' => ':attribute geçerli bir e-posta adresi olmalıdır.',
'min' => [
'string' => ':attribute en az :min karakter olmalıdır.',
],
// ...
];
:attribute yerine alan adı otomatik gelir. Bunu bir kez kurunca tüm projedeki validation’lar Türkçe mesaj gösteriyor; her denetleyicide tekrar yazmıyorsunuz.
unique kuralında bir tuzak
Güncelleme formlarında unique kuralı beklenmedik şekilde davranabilir. Kayıt formunda unique:kullanicilar doğru çalışıyor; var olan e-posta reddediliyor. Ama düzenleme formunda kullanıcının kendi e-postasını değiştirmeden kaydetmesi gerektiğinde kural, o e-postanın tabloda zaten olduğunu görüp hata veriyor.
Bunu aşmak için mevcut kaydın id’sini kural tanımına dahil etmek gerekiyor:
$kurallar = [
'email' => 'required|email|unique:kullanicilar,email,' . $kullanici->id,
];
unique:tablo,sütun,hariç_tutulan_id formatı, o id’ye ait satırı benzersizlik kontrolünün dışında bırakıyor. Bu durumu ilk kez güncelleme formunda keşfettim; kayıt formunda çalışan kural, düzenleme formunda kullanıcının hiçbir şeyi değiştirmeden kaydetmesini engelliyordu.
Neden bu kadar önemli?
Kullanıcı girdisi kontrol edilmezse iki sorun çıkar: uygulama tutarsız veriyle çalışır ve güvenlik açığı oluşur. Laravel’in doğrulama katmanı bunun standart, tekrar edilebilir çözümünü sağlıyor. Artık her formda sıfırdan if zinciri yazmıyorum; kural listesini yazıyorum, geri kalanı framework hallediyor.
Basit bir uygulama gibi görünse de büyük projede onlarca form olduğunda bu standardın değeri katlanarak artıyor. Özellikle bir projeye sonradan dahil olduğunuzda, kuralların merkezi bir yerde tanımlı olması her formun davranışını anlamayı kolaylaştırıyor — denetleyicinin içinde dağınık if blokları aramak zorunda kalmıyorsunuz.