Merhaba arkadaşlar,
Bu yazıda Laravel ile doğrulama (validaiton) işlemlerini olabildiğince geniş bir biçimde anlatmaya çalışacağım. Konu başlıklarımız aşağıdaki gibidir.
- Genel Request nesnesi üzerinden doğrulama
- Özel Request nesnesi üzerinden doğrulama
- Validator nesinesi üzerinden doğrulama
- Kendi kurallarımızı oluşturma (Custom Rule)
- Kendi mesajlarımızı oluşturma (Custom Message)
Öncelikle test yapabilmeniz için hazırlık aşamalarını tamamlayalım. Ben basitçe bir blog sistemi oluşturmayı tercih ettim. İlk önce migration, model, view ve controller dosyalarını oluşturalım.
Migration
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
<?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateBlogsTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('blogs', function (Blueprint $table) { $table->increments('id'); $table->string('title'); $table->text('content'); $table->string('category'); $table->tinyInteger('status'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('blogs'); } } |
Model
1 2 3 4 5 6 7 8 9 10 |
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Blog extends Model { public $fillable = ['title', 'content', 'category', 'status']; } |
View
views/blogs/index.blade.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
@extends('layouts.app') @section('content') <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <div class="panel panel-default"> <div class="panel-heading"> <span>Yazılar</span> <span class="pull-right btn btn-xs btn-default"><a href="{{ route('blogs.create') }}">Yeni Oluştur</a></span> </div> <div class="panel-body"> @if (session('status')) <div class="alert alert-success"> {{ session('status') }} </div> @endif <table class="table table-bordered"> <thead> <tr> <th>Başlık</th> <th>Durum</th> </tr> </thead> <tbody> @foreach($blogs as $blog) <tr> <td>{{ $blog->title }}</td> <td>{{ $blog->status }}</td> </tr> @endforeach </tbody> </table> </div> </div> </div> </div> </div> @endsection |
views/blogs/create.blade.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
@extends('layouts.app') @section('content') <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <div class="panel panel-default"> <div class="panel-heading"> <span>Blog Oluşturma</span> <span class="pull-right btn btn-xs btn-default"><a href="{{ route('blogs.index') }}">Blog Listesi</a></span> </div> <div class="panel-body"> @if (session('status')) <div class="alert alert-success"> {{ session('status') }} </div> @endif @if ($errors->any()) <div class="alert alert-danger"> <ul> @foreach ($errors->all() as $error) <li>{{ $error }}</li> @endforeach </ul> </div> @endif <form action="{{ route('blogs.store') }}" method="post"> <div class="form-group"> <label for="title">Başlık</label> <input type="text" name="title" class="form-control" id="title" placeholder="Blog başlığı.."> </div> <div class="form-group"> <label for="content">İçerik</label> <textarea class="form-control" name="content" id="content" placeholder="Blog içeriği.."></textarea> </div> <div class="form-group"> <label for="category">Kategori</label> <select name="category" id="category" class="form-control"> <option value="Genel">Genel</option> <option value="php">Php</option> <option value="laravel">Laravel</option> <option value="asp.net">Asp.Net</option> <option value="asp.net_mvc">Asp.Net MVC</option> </select> </div> <div class="form-group"> <label for="status">Durum</label> <select name="status" id="status" class="form-control"> <option value="-1">Seçiniz</option> <option value="1">Aktif</option> <option value="0">Pasif</option> </select> </div> <button type="submit" class="btn btn-primary">Gönder</button> {{ csrf_field() }} </form> </div> </div> </div> </div> </div> @endsection |
Controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
<?php namespace App\Http\Controllers; use App\Blog; use Illuminate\Http\Request; class BlogController extends Controller { public function index() { $blogs = Blog::all(); return view('blogs.index', compact('blogs')); } public function create() { return view('blogs.create'); } public function store(Request $request) { $data = \request()->all(); $blog = new Blog(); $blog->fill($data); $blog->save(); return redirect()->route('blogs.index'); } } |
Gerekli ortamı hazırladıktan sonra asıl odak noktamız olan doğrulama (validation) işlemlerine geçebiliriz.
1. Genel Request Nesnesi Üzerinden Doğrulama
Bu yöntem diğerleri arasında en basit ve hızlı olanıdır. İsterseniz Request $request
ile gelen veri üzerinde isterseniz de request()
ile gelen veri üzerinde doğrulama yapabilirsiniz. İkisi de aynı şeydir.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
public function store(Request $request) { $request->validate([ 'title' => 'required|unique:blogs|max:255', 'content' => 'required', ]); // veya \request()->validate([ 'title' => 'required|unique:blogs|max:255', 'content' => 'required', ]); $data = \request()->all(); $blog = new Blog(); $blog->fill($data); $blog->save(); return redirect()->route('blogs.index'); } |
Doğrulama sonucu eğer false
olarak dönerse doğrulama altında kalan satırlar çalıştırılmadan işlem yönlendirilerek bir önceki form sayfası açılır. Böylelikle yanlış veriler kaydetmemiş olursunuz.
2. Validator Nesinesi Üzerinden Doğrulama
Bu yöntemle kendimize özel bir Request nesnesi oluşturarak controller içinde doğrulama kodu yazmadan daha temiz bir şekilde request nesnesi üzerinden doğrulama yapabiliriz. Böylelikle controller içinde sadece gerekli kayıt işlemlerini yapmış oluruz.
1 |
php artisan make:request StoreBlogPost |
Bu komutla request nesnesini oluşturuyoruz. Burada yazılı olmayan bir kuralımız var. Request isminin başında hangi işlem için kullanacağınızı yazmanız okunabilirlik açısından çok faydalı olacaktır. Örneğin bir yazıyı güncelleme sırasında kullanacağınız request ismi UpdateBlogPost
olursa onun ne amaçla yapıldığını içine girmeden sadece ismini görerek de anlamış oluruz.
Komutu çalıştıralım ve oluşan request dosyasının içeriğini aşağıdaki gibi değiştirelim.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
<?php namespace App\Http\Requests; use Illuminate\Foundation\Http\FormRequest; class StoreBlogPost extends FormRequest { /** * Determine if the user is authorized to make this request. * * @return bool */ public function authorize() { return true; } /** * Get the validation rules that apply to the request. * * @return array */ public function rules() { return [ 'title' => 'required|unique:blogs|max:255', 'content' => 'required', ]; } } |
Burada title
değerinin benzersiz olması gerektiğini ve en fazla 255 karakter girilebileceğini belirtmiş olduk. Ayrıca hem title
hem de content
değerleri mutlaka girilmelidir.
Şimdi bunu nasıl kullanacağımıza bakalım. Öncelikle namespace satırı altına use App\Http\Requests\StoreBlogPost;
ekliyoruz. Az önceki kodlarımızdan farklı olarak bu kez $request->validate()
kısmı yok ve store(Request $request)
yerine store(StoreBlogPost $request)
yazdık. Böylelikle controller içindeki kodlarımız daha da azaldı ve StoreBlogPost
içindeki kodlarımız çalışarak doğrulama işini yapmış oldu.
1 2 3 4 5 6 7 8 9 |
public function store(StoreBlogPost $request){ $data = \request()->all(); $blog = new Blog(); $blog->fill($data); $blog->save(); return redirect()->route('blogs.index'); } |
3. Özel Request Nesnesi Üzerinden Doğrulama
Bu yöntemle Validator sınıfı üzerinden doğrulama işlemi yapmaya çalışacağız. İlk önce namespace altına use Validator;
satırını ekliyoruz. Ardından kodumuzu aşağıdaki gibi değiştiriyoruz.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
public function store(Request $request){ $validator = Validator::make($request->all(), [ 'title' => 'required|unique:blogs|max:255', 'content' => 'required', ], [ 'title.required' => 'Bu alan çok ama çok gereklidir. Girmezseniz vallahi çok darılırız :)' ]); if ($validator->fails()) { return redirect('blogs/create')->withErrors($validator)->withInput(); } $data = \request()->all(); $blog = new Blog(); $blog->fill($data); $blog->save(); return redirect()->route('blogs.index'); } |
Validator::make();
3 parametre alıyor. İlk parametre doğrulanacak olan request, ikini paremetre doğrulamada kullanılacak kurallar, üçüncü parametre ise kurallara eğer özel bir kural girdiyseniz onun için gösterilecek mesajdır. Üçüncü parametreye özel bir kural olmasa da değiştirmek istediğiniz bir kuralın mesajını da yazabilirsiniz.
Diğer yöntemlerden farklı olarak bu yöntemde doğrulamanın başarısız olduğu durumda ne yapması gerektiğine siz karar veriyorsunuz. İsterseniz bir hata mesajı ile doğrudan işlemleri durdurabilir, isterseniz de yönlendirme yaparak formda gerekli bilgilendirme mesajını gösterebilirsiniz.
Örnek olması açısından ve hızlıca deneme yapabilmeniz için makaleyi yazarken kullandığım projeden doğrulama kodlarını silerek bir kopyasını sizinle paylaşıyorum. Veritabanı olarak sqlite kullandım. Herhangi bir ek işlem yapmaya gerek kalmadan projeyi açıktan sonra composer update
ve php artisan migrate
komutlarını çalıştırmanız yeterlidir.
Şimdilik anlatacaklarım bu kadar. Daha sonra kendi kurallarımızı ve mesajlarımızı nasıl oluşturabileceğimizi de örneklerle anlatacağım.
Faydalı olması dileğiyle..
Teşekkürler.
Merhaba,
Çoklu unique validataion’u nasıl yapabiliriz?
Saatlerdir arıyorum bir sonuç bulamadım.
Örnek üzerinden derdimi anlatayım. Elimde bir tablo olsun kullanıcılar tablosu, Bu tabloda TC, Email ve Telefon numarası var diyelim.
Kullanıcı kayıt olurken, eğer bu üçüne de uyan kayıt var ise kaydetmesin istiyorum. Yani diyelim ki
11111111111, mymail@domain.com, 0555 555 55 55
bu şekilde bir kayıt var tabloda, biri daha aynı bilgilerle kayıt olmak isterse kayıt olamayacak. Bu bilgilerde biri zaten var diyecek.
Ama bu bilgilerden birisi farklı ile kayıt olabilecek. Örneğin
11111111111, mymail@domain.com, 0555 555 55 56
olarak giriş yapmaya çalışırsa kaydolabilecek.
Elbette tablom bu şekilde değil. Aradığım işlemi anlatabilmek için bu örneği veriyorum.
Laravel 9 kullanıyorum.
Yardımlarınızı rica ederim.