Laravel İle Dinamik Veri Filtreleme Sistemi Nasıl Yapılır?

Laravel İle Dinamik Veri Filtreleme Sistemi Nasıl Yapılır?
Laravel İle Dinamik Veri Filtreleme Sistemi Nasıl Yapılır?

Gereksinimler ve Ön Hazırlık

Dinamik filtreleme sistemi kurabilmek için sisteminizde Laravel 11 veya üzeri bir sürümün yüklü olması önerilir. Veritabanı işlemleri için Eloquent ORM (Object-Relational Mapping) kullanılacaktır. Çalışma ortamınızın hazır olduğundan emin olmak için şu adımları kontrol edin:

  • PHP 8.2 veya daha yeni bir sürüm.
  • Composer paket yöneticisi.
  • Veritabanı bağlantısı yapılandırılmış bir Laravel projesi.
  • Test verileriyle dolu bir model (Örn: Product modeli).

Adım 1: Query Scope Kullanarak Filtreleme Mantığını Ayırma

Laravel'de filtreleme mantığını model içerisinde "Scope" olarak tanımlamak, kodunuzun tekrar kullanılabilirliğini artırır. Scope'lar, sorgu oluşturucunuza özel kısıtlamalar eklemenize olanak tanır. Aşağıdaki örnekte, bir ürün listesini kategori ve fiyat aralığına göre filtreleyen bir scope yapısını görebilirsiniz.


// App/Models/Product.php
public function scopeFilter($query, array $filters)
{
    $query->when($filters['category'] ?? null, function ($q, $category) {
        $q->where('category_id', $category);
    });

    $query->when($filters['min_price'] ?? null, function ($q, $price) {
        $q->where('price', '>=', $price);
    });
}

Burada kullanılan when metodu, eğer filtre değeri mevcutsa sorguya ekleme yapar. Bu sayede gereksiz SQL sorgularından kaçınmış olursunuz.

Adım 2: Controller Üzerinde İstekleri Yönetme

Filtreleme parametrelerini Request nesnesi üzerinden alarak modele aktarmak en temiz yöntemdir. Kullanıcıdan gelen verilerin doğrulanması (validation), güvenlik açısından zorunludur. Aşağıdaki örnekte, gelen verilerin nasıl işlendiğini inceleyelim.


// App/Http/Controllers/ProductController.php
public function index(Request $request)
{
    $validated = $request->validate([
        'category' => 'nullable|integer',
        'min_price' => 'nullable|numeric',
    ]);

    $products = Product::filter($validated)->get();

    return view('products.index', compact('products'));
}

Bu kod bloğu, sadece geçerli verilerin sorguya girmesini sağlar. nullable kuralı, kullanıcının filtre seçmediği durumlarda sistemin hata vermesini engeller.

Adım 3: Dinamik Filtreleme Yöntemlerinin Karşılaştırılması

Filtreleme yaparken tercih edebileceğiniz farklı yöntemler mevcuttur. Aşağıdaki tablo, projelerinizde doğru yöntemi seçmenize yardımcı olacaktır.

Yöntem Avantajı Dezavantajı
Query Scopes Temiz ve okunabilir kod Çok karmaşık mantıklarda şişebilir
Query Filter Classes Her filtre için ayrı sınıf (SOLID) Küçük projeler için fazla dosya yükü
API Resources Veri formatını kontrol etme Sorgu katmanından bağımsızdır

Adım 4: Gelişmiş Filtreleme İçin Pipeline Kullanımı

Projeniz büyüdükçe, her filtreyi ayrı sınıflara bölmek (Pipeline Pattern) en iyi pratik olarak kabul edilir. Bu yaklaşım, kodunuzun "Single Responsibility" (Tek Sorumluluk) prensibine uymasını sağlar. Her filtre sınıfı kendi içerisinde tek bir mantığı yönetir.


// App/Filters/PriceFilter.php
public function handle($query, $next)
{
    if (request()->has('min_price')) {
        $query->where('price', '>=', request('min_price'));
    }
    return $next($query);
}

Bu yapı sayesinde, yeni bir filtre eklemek istediğinizde mevcut kodunuzu değiştirmek yerine sadece yeni bir sınıf oluşturmanız yeterli olacaktır.

Adım 5: Güvenlik ve Performans İpuçları

Dinamik filtreleme yaparken dikkat etmeniz gereken en önemli husus SQL Injection saldırılarıdır. Laravel'in Eloquent yapısı, parametre bağlama (parameter binding) kullanarak sizi bu saldırılardan korur. Ancak, ham SQL sorguları yazarken dikkatli olmalısınız.

Kritik Güvenlik Uyarısı: Kullanıcıdan gelen verileri asla doğrudan sorgu içerisinde değişken olarak kullanmayın. Her zaman Eloquent metodlarını veya Query Builder'ın sunduğu güvenli parametre bağlama yöntemlerini tercih edin. Üretim ortamında (production) mutlaka "Query Caching" kullanarak veritabanı üzerindeki yükü azaltın.

Performansı artırmak için filtreleme yaptığınız sütunlara veritabanında mutlaka index (dizin) eklemeyi unutmayın. Özellikle price veya created_at gibi sık filtrelenen alanlar için index kullanımı sorgu süresini milisaniyelere düşürür.

Sıkça Sorulan Sorular

Filtreleme sisteminde boş parametreler sorguyu yavaşlatır mı?

Laravel'in when metodu, değer boşsa sorguya dahil edilmediği için veritabanına ek bir yük bindirmez. Bu nedenle güvenle kullanabilirsiniz.

Arama (Search) özelliği ile filtreleme nasıl birleştirilir?

Aynı filter scope içerisine where('name', 'like', '%' . $search . '%') ekleyerek arama ve filtrelemeyi tek bir sorguda birleştirebilirsiniz.

Çok fazla filtre olduğunda kod karmaşasını nasıl önlerim?

Yukarıda bahsettiğimiz "Pipeline" veya "Filter Classes" yöntemini kullanarak her filtreyi kendi sınıfına taşıyarak kodunuzu modüler hale getirebilirsiniz.

Kullanıcı filtreleri URL'de nasıl tutulmalı?

Query string (Örn: ?category=1&min_price=100) kullanmak, kullanıcıların filtreli sayfaları paylaşabilmesi ve tarayıcı geçmişinde tutabilmesi için en ideal yöntemdir.

Sayfalama (Pagination) ile filtreleme nasıl çalışır?

Eloquent'te get() yerine paginate() metodunu kullanmanız yeterlidir. Laravel, filtre parametrelerini otomatik olarak sayfalama linklerine ekleyecektir.

Filtreleme Sistemlerinde Hata Ayıklama ve Loglama Stratejileri

Dinamik filtreleme sistemleri, özellikle çok sayıda parametrenin birleştiği durumlarda beklenmedik SQL sonuçları üretebilir. Sistemin hangi filtreleri uyguladığını ve arka planda çalışan SQL sorgusunun yapısını görmek, hata ayıklama sürecini hızlandırır. Laravel'in DB::enableQueryLog() özelliğini kullanarak, filtreleme sonucunda oluşan sorguları inceleyebilirsiniz.

Aşağıdaki yöntem, geliştirme aşamasında filtreleme mantığınızı test etmek için idealdir:

// AppServiceProvider veya ilgili Controller içerisinde
use Illuminate\Support\Facades\DB;

public function index(Request $request) {
    DB::enableQueryLog();

    $products = Product::filter($request->all())->get();

    // Çalışan sorguyu ve bağlanan parametreleri görüntüle
    dd(DB::getQueryLog());
}

Üretim ortamında (production) ise sorgu loglarını doğrudan ekrana yazdırmak yerine, Log facade'ını kullanarak belirli bir kanal üzerinden dosyalara yazmak daha güvenlidir. Bu sayede kullanıcı deneyimini bozmadan, hatalı filtre kombinasyonlarını tespit edebilirsiniz.

Filtreleme Performansını Optimize Etmek İçin İndeksleme

Dinamik filtreleme sistemlerinde en büyük performans darboğazı, veritabanı tablolarında uygun indekslerin bulunmamasıdır. Filtreleme yaptığınız sütunlar (örneğin: category_id, price, status) üzerinde indeks oluşturulmadığında, veritabanı her sorguda tüm tabloyu tarar (Full Table Scan). Bu durum, veri seti büyüdükçe uygulamanızın yavaşlamasına neden olur.

Filtreleme performansını artırmak için kullanabileceğiniz veritabanı optimizasyon ipuçları:

  • Tekil İndeksler: En çok filtrelenen sütunlar için $table->index('column_name'); göçlerini (migration) kullanın.
  • Bileşik İndeksler (Composite Indexes): Eğer sorgularınızda sıklıkla category_id ve status sütunlarını birlikte kullanıyorsanız, tekil indeksler yerine bileşik indeks oluşturmak performansı ciddi oranda artırır: $table->index(['category_id', 'status']);.
  • Kapsayıcı İndeksler: Sadece filtreleme yaptığınız sütunları değil, sorgu sonucunda döndürdüğünüz sütunları da kapsayan indeksler (Covering Indexes) kullanarak veritabanının tabloya gitmeden sadece indeks üzerinden cevap vermesini sağlayabilirsiniz.

Aşağıdaki örnek, bir veritabanı göç dosyasında performans odaklı indeks tanımlamasını göstermektedir:

Schema::table('products', function (Blueprint $table) {
    // Filtreleme hızını artırmak için bileşik indeks
    $table->index(['price', 'created_at']);
    // Arama özelliği için tam metin indeksi
    $table->fullText('description');
});

Unutmayın, her sütuna indeks eklemek yazma (insert/update) işlemlerini yavaşlatabilir. Bu nedenle, indeksleme stratejinizi uygulamanızın okuma/yazma oranına göre dengelemelisiniz.

Sonuç

Laravel ile dinamik veri filtreleme sistemi oluşturmak, uygulamanızın profesyonellik seviyesini bir üst noktaya taşır. Bu rehberde öğrendiğiniz Query Scope ve Pipeline yöntemleri, sürdürülebilir ve güvenli kod yazmanız için temel taşlardır. Bir sonraki adım olarak, bu filtreleme sistemini "Livewire" ile entegre ederek sayfa yenilenmeden çalışan "Ajax" tabanlı bir filtreleme arayüzü geliştirmeyi deneyebilirsiniz. Yazılım geliştirme sürecinde her zaman temiz kod (clean code) prensiplerine sadık kalarak, uygulamanızın uzun ömürlü olmasını sağlayabilirsiniz.

Sorumluluk Reddi: Bu makalede yer alan kod örnekleri eğitim amaçlıdır. Uygulamanızın canlı ortamına almadan önce mutlaka kapsamlı bir güvenlik testi yapmalı ve girdi doğrulamalarını (validation) eksiksiz tamamlamalısınız.

Bu yazıya tepkinizi paylaşın:
Deniz Arslan

On yıldır pratik ev çözümleri ve hayat kolaylaştıran teknikler üzerine içerik üretiyorum. Okuyucuların karmaşık süreçleri en basit adımlarla çözmelerine yardımcı oluyorum.

Yorumlar (0)

Yorum Yaz