Ö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ı motorunuzunInnoDBveyaMyISAMolduğundan emin olun. Ayrıca, çok kısa kelimelerin (genellikle 3 karakter altı) varsayılan olarak yoksayıldığını unutmayın; bu ayarımy.cnfdosyasındakift_min_word_lenparametresi 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.


Yorumlar (0)
Yorum Yaz