Php İle Veritabanı Destekli Bir Arama Filtreleme Sistemi Nasıl Yapılır?

Php İle Veritabanı Destekli Bir Arama Filtreleme Sistemi Nasıl Yapılır?
Php İle Veritabanı Destekli Bir Arama Filtreleme Sistemi Nasıl Yapılır?

Ön Hazırlık ve Gereksinimler

Projeye başlamadan önce geliştirme ortamınızın güncel olduğundan emin olmalısınız. 2026 standartlarına uygun olarak PHP 8.2 veya üzeri bir sürüm kullanmanız, performans ve güvenlik güncellemelerinden yararlanmanızı sağlar. Ayrıca yerel sunucunuzda MySQL veya MariaDB veritabanı yönetim sisteminin kurulu olması gerekmektedir.

  • PHP 8.2+ Sürümü: Modern sözdizimi ve tip güvenliği için.
  • PDO Sürücüsü: Veritabanı bağlantılarında güvenliği sağlamak için.
  • MySQL Veritabanı: Verilerin saklanacağı tablo yapısı.
  • Düzenleyici: VS Code veya benzeri bir editör.

Veritabanı Yapısının Kurulması

Arama sisteminin düzgün çalışması için veritabanında üzerinde arama yapabileceğimiz bir tabloya ihtiyaç vardır. "urunler" adında bir tablo oluşturarak örnek verilerimizi ekleyelim. Bu tablo, arama sonuçlarını test etmemiz için temel teşkil edecektir.


CREATE TABLE urunler (
    id INT AUTO_INCREMENT PRIMARY KEY,
    urun_adi VARCHAR(255) NOT NULL,
    kategori VARCHAR(100),
    fiyat DECIMAL(10, 2),
    eklenme_tarihi TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

INSERT INTO urunler (urun_adi, kategori, fiyat) VALUES 
('Akıllı Telefon X', 'Elektronik', 15000.00),
('Dizüstü Bilgisayar Pro', 'Elektronik', 35000.00),
('Ofis Koltuğu', 'Mobilya', 2500.00),
('Kitaplık', 'Mobilya', 1200.00);

Yukarıdaki SQL komutları, arama sistemini test etmek için gereken tabloyu ve örnek verileri oluşturur. Veritabanı tasarımı yaparken, arama yapılacak sütunların (örneğin urun_adi) indekslenmiş olması, büyük veri setlerinde performans artışı sağlar.

PDO ile Güvenli Veritabanı Bağlantısı

Veritabanı bağlantısını gerçekleştirmek için PDO kullanacağız. PDO, SQL Injection gibi yaygın güvenlik açıklarını önlemek için hazırlanan ifadeleri (prepared statements) destekler. Aşağıdaki kod bloğu, veritabanı bağlantı sınıfını veya değişkenlerini tanımlar.


$host = 'localhost';
$db   = 'magaza_db';
$user = 'root';
$pass = '';
$charset = 'utf8mb4';

$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
try {
    $pdo = new PDO($dsn, $user, $pass, [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
    ]);
} catch (PDOException $e) {
    die("Bağlantı hatası: " . $e->getMessage());
}

Bu bağlantı yapısı, veritabanı hatalarını bir exception (istisna) olarak fırlatır ve bağlantı hatası durumunda uygulamanın kilitlenmesini engeller. utf8mb4 karakter seti, Türkçe karakterlerin doğru işlenmesi için zorunludur.

Arama Formu ve Veri İşleme

Kullanıcıdan arama terimini alacak basit bir HTML formu oluşturmamız gerekiyor. Formun GET metodunu kullanması, arama sonuçlarının URL üzerinden paylaşılabilir olmasını sağlar. Bu, kullanıcı deneyimi açısından kritik bir noktadır.



    
            
                
                
                 TL
            
        
    

Tablo içerisinde number_format fonksiyonu kullanılarak fiyat verisi daha okunabilir hale getirilmiştir. Verilerin her biri yine htmlspecialchars ile filtrelenerek güvenlik katmanı güçlendirilmiştir.

Yöntem Karşılaştırması

Yöntem Avantajı Dezavantajı
PDO (Prepared Statements) Yüksek güvenlik, SQL Injection direnci Küçük bir öğrenme eğrisi
mysqli (Procedural) Hızlı başlangıç Güvenlik hatalarına daha açık
Full-Text Search (MySQL) Çok büyük verilerde yüksek hız Ek yapılandırma gerektirir
Kritik Güvenlik Uyarısı: Kullanıcıdan gelen verileri asla doğrudan SQL sorgularına dahil etmeyin. Her zaman PDO hazırlık ifadelerini (prepared statements) kullanın. Üretim ortamında (production) veritabanı hatalarını kullanıcıya göstermeyin, bunun yerine hata loglarını bir dosyaya kaydedin.

Sıkça Sorulan Sorular

Arama sonuçlarını nasıl sayfalandırabilirim (pagination)?

Sayfalama yapmak için SQL sorgusuna LIMIT ve OFFSET ifadeleri eklemelisiniz. Toplam kayıt sayısını COUNT(*) ile alıp, mevcut sayfa numarasına göre verileri parçalar halinde çekebilirsiniz.

Çoklu sütunda arama yapmak için ne yapmalıyım?

SQL sorgunuzu WHERE urun_adi LIKE :terim OR kategori LIKE :terim şeklinde genişleterek birden fazla sütunda aynı anda arama yapabilirsiniz.

Arama sistemini hızlandırmak için ne yapabilirim?

Arama yapılan sütunlara (örneğin urun_adi) veritabanı üzerinde INDEX eklemek, arama hızını ciddi oranda artıracaktır.

Büyük harf/küçük harf duyarlılığını nasıl yönetirim?

MySQL'de varsayılan karşılaştırma (collation) genellikle duyarsızdır (case-insensitive). Eğer duyarlı olsun isterseniz, sorguda BINARY anahtar kelimesini kullanabilirsiniz.

Arama kutusuna özel karakter girilirse ne olur?

PDO hazırlık ifadeleri, özel karakterlerin SQL komutu olarak yorumlanmasını engeller. Bu yüzden veritabanınız güvende kalır.

Arama Sistemlerinde AJAX ile Canlı Filtreleme (Real-time Search)

Kullanıcı deneyimini iyileştirmek için arama sonuçlarının sayfa yenilenmeden, kullanıcı klavyeden her tuşa bastığında güncellenmesi modern web uygulamalarının standartıdır. Bu yöntem, sunucuya asenkron istekler göndererek veritabanından gelen verileri anlık olarak DOM'a yansıtır.

İstemci Tarafı (JavaScript/Fetch API)

Arama kutusuna girilen veriyi dinlemek için input event'ini kullanırız. Aşağıdaki örnek, kullanıcının yazmayı bırakmasından kısa bir süre sonra (debounce) sorguyu tetikler.

const searchInput = document.getElementById('search-box');
const resultsContainer = document.getElementById('results');

searchInput.addEventListener('input', function() {
    const query = this.value;
    if (query.length > 2) {
        fetch(`search_endpoint.php?q=${encodeURIComponent(query)}`)
            .then(response => response.text())
            .then(data => {
                resultsContainer.innerHTML = data;
            });
    }
});

Sunucu Tarafı (PHP Endpoint)

AJAX isteğini karşılayan search_endpoint.php dosyası, veritabanından verileri çekip sadece sonuçları içeren HTML parçacığını döndürmelidir.

// search_endpoint.php
require 'db.php';
$q = $_GET['q'] ?? '';

$stmt = $pdo->prepare("SELECT title FROM products WHERE title LIKE :q");
$stmt->execute(['q' => '%' . $q . '%']);
$results = $stmt->fetchAll();

foreach ($results as $row) {
    echo "
" . htmlspecialchars($row['title']) . "
"; }

Arama Performansını İleri Seviyeye Taşıma: Full-Text Search

Küçük ölçekli projelerde LIKE operatörü yeterli olsa da, binlerce satırlık veritabanlarında arama performansı düşebilir. MySQL'in Full-Text Index özelliği, metin tabanlı aramalarda çok daha hızlı sonuçlar verir.

Full-Text Index Kurulumu

Öncelikle arama yapılacak sütunlara bir indeks eklemelisiniz:

ALTER TABLE products ADD FULLTEXT(title, description);

MATCH AGAINST Kullanımı

Sorgunuzu LIKE yerine MATCH...AGAINST yapısına çevirerek veritabanı motorunun indekslenmiş veriler üzerinde arama yapmasını sağlayabilirsiniz:

$sql = "SELECT *, MATCH(title, description) AGAINST(:q) AS score 
        FROM products 
        WHERE MATCH(title, description) AGAINST(:q IN NATURAL LANGUAGE MODE)
        ORDER BY score DESC";

$stmt = $pdo->prepare($sql);
$stmt->execute(['q' => $userInput]);

Bu yöntem, sonuçları alaka düzeyine (relevance score) göre sıralamanıza da olanak tanır. score değeri yüksek olan sonuçlar, aranan kelime ile en alakalı olanlardır.

İpucu: Full-Text Search kullanırken, veritabanı motorunuzun InnoDB veya MyISAM olduğundan emin olun. Ayrıca, çok kısa kelimelerin (genellikle 3 karakter altı) varsayılan olarak yoksayıldığını unutmayın; bu ayarı my.cnf dosyasındaki ft_min_word_len parametresi ile değiştirebilirsiniz.

Sonuç

Php ile veritabanı destekli bir arama filtreleme sistemi oluşturmak, doğru güvenlik pratikleri uygulandığında oldukça basit ve etkili bir süreçtir. Bu rehberde öğrendiğiniz PDO kullanımı, veri temizleme ve SQL sorgu yapılandırması, uygulamanızın temelini oluşturacaktır. Bir sonraki adım olarak, arama sonuçlarını AJAX ile sayfayı yenilemeden getiren bir yapı kurarak kullanıcı deneyimini bir üst seviyeye taşıyabilirsiniz.

Kod güvenliği sorumluluk reddi: Bu rehberde paylaşılan kodlar eğitim amaçlıdır. Uygulamanızı canlıya almadan önce mutlaka profesyonel bir güvenlik testinden geçirin ve veritabanı yetkilendirmelerini (user privileges) en düşük seviyede tutun.

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

On yıldır dijital yayıncılıkta pratik çözüm rehberleri hazırlıyorum. Karmaşık süreçleri herkesin anlayabileceği adım adım yönergelere dönüştürme konusunda uzmanım.

Yorumlar (0)

Yorum Yaz