Php İle Nesne Yönelimli Yapıda Dinamik Site İçi Yorum Filtreleme Nasıl Yapılır?

Php İle Nesne Yönelimli Yapıda Dinamik Site İçi Yorum Filtreleme Nasıl Yapılır?
Php İle Nesne Yönelimli Yapıda Dinamik Site İçi Yorum Filtreleme Nasıl Yapılır?

Gereksinimler ve Ön Hazırlık

Bu projeyi hayata geçirmek için bilgisayarınızda bir yerel geliştirme ortamının kurulu olması gerekir. PHP 8.2 veya daha yeni bir sürüm, modern sözdizimi ve performans iyileştirmeleri için önerilir. Ayrıca veritabanı işlemleri için PDO (PHP Data Objects) kullanacağız.

  • PHP 8.2+ sürümü
  • MySQL veya MariaDB veritabanı sunucusu
  • Composer (isteğe bağlı, ancak bağımlılık yönetimi için önerilir)
  • Temel düzeyde OOP bilgisi (Class, Interface, Dependency Injection)

Yorum Filtreleme Sınıfı Tasarımı

Nesne yönelimli yapıda, her parçanın tek bir sorumluluğu olmalıdır (Single Responsibility Principle). Filtreleme işlemini bir sınıf içerisinde tutarak, kodun tekrar kullanılabilirliğini artıracağız. Aşağıdaki kod bloğu, temel filtreleme sınıfımızın iskeletini oluşturur.


class CommentFilter {
    private array $bannedWords = ['kötü', 'yasaklı', 'spam'];

    public function sanitize(string $input): string {
        // XSS saldırılarına karşı temizleme
        $data = htmlspecialchars($input, ENT_QUOTES, 'UTF-8');
        return trim($data);
    }

    public function checkProfanity(string $input): bool {
        foreach ($this->bannedWords as $word) {
            if (stripos($input, $word) !== false) {
                return false;
            }
        }
        return true;
    }
}

Bu sınıf, sanitize metodu ile kullanıcı girişini HTML etiketlerinden arındırır, checkProfanity metodu ile de yasaklı kelime kontrolü yapar. stripos fonksiyonu, büyük/küçük harf duyarlılığı olmadan arama yapmamızı sağlar.

Dinamik Filtreleme İçin Veritabanı Entegrasyonu

Yasaklı kelimelerin kod içerisinde sabitlenmesi (hard-coded) esnekliği azaltır. Bu nedenle, yasaklı kelimeleri veritabanında tutmalı ve dinamik olarak çekmeliyiz. Aşağıdaki örnekte, veritabanından gelen yasaklı kelimeleri kullanan bir yapı kuruyoruz.


class DynamicFilter {
    private PDO $db;

    public function __construct(PDO $db) {
        $this->db = $db;
    }

    public function getBannedWords(): array {
        $stmt = $this->db->query("SELECT word FROM banned_words");
        return $stmt->fetchAll(PDO::FETCH_COLUMN);
    }

    public function isClean(string $content): bool {
        $words = $this->getBannedWords();
        foreach ($words as $word) {
            if (stripos($content, $word) !== false) return false;
        }
        return true;
    }
}

Bu yapıda, veritabanı bağlantısını sınıfın kurucu metoduna (constructor) enjekte ederek (Dependency Injection), sınıfın bağımsızlığını koruyoruz. Bu sayede test edilebilirliği artırmış oluyoruz.

Yorumları Filtreleyerek Kaydetme Süreci

Kullanıcıdan gelen veriyi doğrudan veritabanına yazmak büyük bir güvenlik açığıdır. Hazırladığımız sınıfları birleştirerek, güvenli bir kayıt süreci oluşturalım. Burada prepare ve execute kullanarak SQL Injection saldırılarını engelliyoruz.


$db = new PDO('mysql:host=localhost;dbname=blog', 'root', '');
$filter = new DynamicFilter($db);

$userInput = $_POST['comment'] ?? '';
$cleanInput = htmlspecialchars($userInput, ENT_QUOTES, 'UTF-8');

if ($filter->isClean($cleanInput)) {
    $stmt = $db->prepare("INSERT INTO comments (content) VALUES (:content)");
    $stmt->execute(['content' => $cleanInput]);
    echo "Yorum başarıyla kaydedildi.";
} else {
    echo "Yorumunuz yasaklı kelimeler içeriyor!";
}

Bu kod bloğu, kullanıcının gönderdiği yorumu önce temizler, ardından filtre kontrolünden geçirir. Eğer yorum temizse veritabanına ekler, değilse kullanıcıyı uyarır.

Filtreleme Yöntemlerinin Karşılaştırılması

Yöntem Avantajı Dezavantajı
Sabit Dizi (Array) Çok hızlı, kurulumu kolay Güncellemek için kod değişikliği gerekir
Veritabanı (Dynamic) Yönetim paneli ile kolayca güncellenir Her sorguda ek yük (overhead) oluşturur
Regex (Düzenli İfadeler) Karmaşık kalıpları yakalar Performans maliyeti yüksektir
Kritik Güvenlik Uyarısı: Sadece sunucu tarafında filtreleme yapmak yeterli değildir. Kullanıcı deneyimini artırmak için JavaScript ile istemci tarafında da anlık kontrol yapmalısınız. Ancak, sunucu tarafındaki doğrulama (server-side validation) nihai güvenlik katmanıdır ve asla atlanmamalıdır.

Yaygın Hatalar ve Debug İpuçları

Yorum filtreleme geliştirirken yapılan en yaygın hata, veritabanı sorgularını döngü içerisine koymaktır. Her kelime kontrolü için veritabanına gitmek, sitenizi yavaşlatır. Bunun yerine, yasaklı kelimeleri bir kez çekip bellekte (array) tutmak en iyi pratiklerden biridir.


// Hatalı Yaklaşım (Döngü içinde sorgu)
foreach($userWords as $word) {
    $db->query("SELECT * FROM banned WHERE word = '$word'");
}

// Doğru Yaklaşım (Tümünü tek seferde çek)
$banned = $db->query("SELECT word FROM banned")->fetchAll(PDO::FETCH_COLUMN);
// Şimdi bellekte kontrol et

Debug yaparken var_dump() yerine error_log() kullanın. Bu, hataların sunucu log dosyalarına düşmesini sağlar ve üretim ortamında kullanıcıya hata mesajı gösterme riskini ortadan kaldırır.

Sıkça Sorulan Sorular

Yasaklı kelimeler listesini nasıl güncel tutabilirim?

Bir admin paneli oluşturarak veritabanındaki banned_words tablosuna yeni kelimeler ekleyebilir veya çıkarabilirsiniz. Kod tarafında herhangi bir değişiklik yapmanıza gerek kalmaz.

Regex mi yoksa strpos mu kullanmalıyım?

Basit kelime engelleme işlemleri için stripos veya strpos çok daha hızlıdır. Ancak, "kötü kelime"nin farklı varyasyonlarını (örn: k.ö.t.ü) engellemek istiyorsanız Regex kullanmanız gerekir.

Bu yapı büyük ölçekli sitelerde performans sorunu yaratır mı?

Yasaklı kelimeler listesi çok büyükse (binlerce kelime), bu listeyi Redis gibi bir önbellekleme (caching) sisteminde tutmak performansı ciddi oranda artıracaktır.

HTML etiketlerini tamamen yasaklamalı mıyım?

Evet, yorum alanlarında HTML etiketlerine izin vermek XSS saldırılarına davetiye çıkarır. Eğer biçimlendirme istiyorsanız, Markdown veya güvenli bir HTML kütüphanesi (örneğin HTML Purifier) kullanmalısınız.

PHP'de nesne yönelimli yapının avantajı nedir?

OOP, kodunuzu modüler hale getirir. Filtreleme mantığını değiştirmek istediğinizde, tüm projeyi değil sadece ilgili sınıfı güncellersiniz. Bu da bakım maliyetini düşürür.

Gelişmiş Filtreleme İçin Stratejik İpuçları ve Optimizasyon

Sisteminizi daha dayanıklı hale getirmek için sadece kelime bazlı filtreleme yeterli olmayabilir. Kullanıcıların filtreleri aşmak için kullandığı "leetspeak" (örneğin 'a' yerine '4', 's' yerine '$' kullanmak) gibi teknikleri engellemek adına, veriyi normalize eden bir katman eklemelisiniz. Bu katman, veritabanına kaydetmeden önce metni standart bir formata dönüştürür.

Normalizasyon Katmanı ile Güvenliği Artırma

Aşağıdaki TextNormalizer sınıfı, kullanıcı girdisindeki özel karakterleri temizleyerek filtreleme motorunuzun daha isabetli çalışmasını sağlar.

class TextNormalizer {
    public static function clean($text) {
        $map = [
            '4' => 'a', '@' => 'a', '3' => 'e', 
            '1' => 'i', '!' => 'i', '0' => 'o', '$' => 's'
        ];
        $text = strtr(strtolower($text), $map);
        return preg_replace('/[^a-z0-9\s]/', '', $text);
    }
}

// Kullanım örneği:
$rawInput = "Bu bir 4rgo m3saj!";
$cleanInput = TextNormalizer::clean($rawInput);
// $cleanInput artık "bu bir argo mesaj" değerini döndürür.

Filtreleme Sisteminde Performans İzleme ve Test

Yorum trafiğinin yoğun olduğu platformlarda, her yorum için veritabanına gidip yasaklı kelimeleri sorgulamak darboğaz yaratabilir. Bu noktada Redis veya Memcached gibi bir önbellekleme (caching) mekanizması kullanmak, veritabanı üzerindeki yükü %90 oranında azaltacaktır.

Önbellekleme ile Sorgu Yükünü Hafifletme

Yasaklı kelimeler listesini her istekte veritabanından çekmek yerine, sistemin ilk açılışında belleğe yükleyerek hızlı erişim sağlayabilirsiniz.

class CachedFilter extends CommentFilter {
    private $cache;

    public function __construct($db, $cacheProvider) {
        parent::__construct($db);
        $this->cache = $cacheProvider;
    }

    public function getForbiddenWords() {
        if (!$this->cache->has('forbidden_words')) {
            $words = parent::getForbiddenWords();
            $this->cache->set('forbidden_words', $words, 3600);
        }
        return $this->cache->get('forbidden_words');
    }
}

Birim Testleri (Unit Testing) ile Doğrulama

Sisteminizi canlıya almadan önce, farklı senaryoları kapsayan otomatik testler yazmanız kritik önem taşır. PHPUnit kullanarak, filtreleme sınıfınızın beklenen sonuçları verip vermediğini kontrol edin.

Senaryo Girdi Beklenen Sonuç
Temiz Metin "Harika bir içerik" Geçerli
Yasaklı Kelime "Kötü kelime" Engellendi
Leetspeak "K0tü k3lim3" Engellendi

Bu testleri phpunit aracılığıyla çalıştırarak, yaptığınız güncellemelerin mevcut filtreleme mantığını bozmadığından emin olabilirsiniz. Unutmayın; iyi bir yazılım, sadece çalışan değil, aynı zamanda test edilebilir ve geliştirilebilir olandır.

Sonuç

Bu rehberde, PHP ile nesne yönelimli bir yapıda nasıl dinamik yorum filtreleme sistemi kuracağınızı adım adım inceledik. OOP prensiplerini, veritabanı entegrasyonunu ve temel güvenlik önlemlerini birleştirerek profesyonel bir yaklaşım sergiledik. Bir sonraki adım olarak, bu sisteme bir "Yasaklı IP" engelleme mekanizması ekleyebilir veya filtreleme başarısızlıklarını loglayan bir "Güvenlik Raporlama" sınıfı geliştirebilirsiniz.

Sorumluluk Reddi: Bu makalede paylaşılan kod örnekleri eğitim amaçlıdır. Üretim ortamında (production) kullanmadan önce, veritabanı bağlantı bilgilerini güvenli bir şekilde (env dosyaları gibi) saklamalı ve uygulamanızı kapsamlı güvenlik testlerinden geçirmelisiniz.
Bu yazıya tepkinizi paylaşın:
Pelin Aydın

Kullanıcı deneyimi odaklı içerik stratejileri geliştiriyorum. Pratik bilgi arayan okuyucular için en hızlı ve etkili yöntemleri içeren rehberler hazırlıyorum.

Yorumlar (0)

Yorum Yaz