SQL Injection koruması, XSS filtresi ve temiz katmanlı mimariyle geliştirilmiş PHP 8 rapor modülü. Tek satırla rapor oluşturun, CSV indirin, stored procedure çalıştırın.
// Tek satır include yeterli require_once __DIR__ . '/cls/Raporlar.php'; $raporlar = new Raporlar($pdo); // Filtresiz rapor $raporlar->RaporOlustur('satis_raporu'); // Filtreli rapor — SQL Injection yok $raporlar->RaporOlustur( raporad: 'satis_raporu', where: 'tarih >= :bas AND tarih <= :bit', kosullar: [':bas' => '2025-01-01', ':bit' => '2025-12-31'] ); // CSV indir $raporlar->exportExcel('satis_raporu'); exit;
Karmaşık kurulum yok, framework bağımlılığı yok. Sadece include edin ve kullanmaya başlayın.
Sadece Raporlar.php include edin. Diğer dosyalar otomatik yüklenir.
Tüm sorgular PDO prepared statement ile çalışır. Kullanıcı girdisi asla doğrudan SQL'e girmez.
Named placeholder sistemiyle dinamik WHERE koşulları güvenle oluşturulur ve birleştirilebilir.
UTF-8 BOM ile Türkçe karakter destekli gerçek CSV. Tarayıcı doğrudan indirmeye başlar.
Birden fazla result set döndüren stored procedure'ler nextRowset() ile desteklenir.
Repository, Renderer ve Exporter ayrı sınıflarda. Her biri bağımsız kullanılabilir ve test edilebilir.
Her sınıf tek bir işi yapar. Veri çekme, HTML üretme ve export birbirinden tamamen ayrılmış.
Veritabanı sorgularını yönetir. Tablo, view ve stored procedure'den veri çeker. HTML üretmez.
Repository'den aldığı veriyi HTML tabloya dönüştürür. Veritabanına hiç dokunmaz.
Veriyi gerçek CSV formatında dışa aktarır. HTML tablo değil, doğrudan fputcsv kullanır.
Tüm alt sınıfları bir araya getirir. Dışarıya tek giriş noktası sunar, geriye dönük uyumluluk sağlar.
Basit listeden stored procedure'e, CSV export'tan JOIN sorgusuna kadar tüm kullanım biçimleri.
// raporlar tablosunda raporad='satis_raporu' kaydı olmalı // kaynak alanı: tablo adı veya view adı $raporlar = new Raporlar($pdo); $raporlar->RaporOlustur('satis_raporu');
// WHERE cümlesi şablon, değerler ayrı geçirilir → SQL Injection yok $where = 'tarih >= :bas AND tarih <= :bit'; $kosullar = [':bas' => '2025-01-01', ':bit' => '2025-12-31']; // Ek koşul dinamik olarak eklenebilir if ($musteriId > 0) { $where .= ' AND musteri_id = :mid'; $kosullar[':mid'] = $musteriId; } $raporlar->RaporOlustur( raporad: 'satis_raporu', where: $where, kosullar: $kosullar );
// raporlar tablosundaki kaynak alanı: stored procedure adı // Parametreler sıralı → CALL sp_aylik_ozet('2025', '03') $raporlar->RaporOlusturSSP( raporad: 'aylik_ozet', parametreler: ['2025', '03'], kolonAdlari: ['ay', 'toplam_satis', 'adet'] ); // Birden fazla result set döndüren SP → nextRowset() ile $stmt = $pdo->prepare("CALL sp_aylik_ozet(:yil, :ay)"); $stmt->execute([':yil' => '2025', ':ay' => '03']); $ozet = $stmt->fetch(PDO::FETCH_OBJ); $stmt->nextRowset(); $urunDagilim = $stmt->fetchAll(PDO::FETCH_OBJ); $stmt->closeCursor();
// export çağrısı HTML'den ÖNCE yapılmalı — header() gönderir // Filtresiz $raporlar->exportExcel('satis_raporu'); exit; // WHERE filtreli $raporlar->exportExcel( raporad: 'satis_raporu', where: 'musteri_id = :mid', kosullar: [':mid' => $musteriId] ); exit; // Stored procedure CSV $exporter->exportCSVSSP( raporad: 'aylik_ozet', parametreler: ['2025', '06'], kolonAdlari: ['ay', 'toplam', 'adet'] ); exit;
// JOIN veya karmaşık sorgular için — rapor tanımı gerekmez // $sorgu içine kullanıcı girdisi YAZILMAZ, $kosullar ile geçirilir $raporlar->RaporOlusturWithQuery( sorgu: 'SELECT k.ad, k.soyad, k.email, COUNT(s.id) AS satis_adeti, SUM(s.tutar) AS toplam_tutar FROM kullanicilar k LEFT JOIN satislar s ON s.kullanici_id = k.id WHERE k.durum = :durum GROUP BY k.id ORDER BY toplam_tutar DESC', kolonAdlari: ['ad', 'soyad', 'email', 'satis_adeti', 'toplam_tutar'], kosullar: [':durum' => $durum], raporad: 'kullanici_ozeti' );
// Alt sınıfları doğrudan kullanmak: HTML'i değişkene al, şablona göm $repo = new RaporRepository($pdo); $renderer = new RaporRenderer($repo); $exporter = new RaporExporter($repo); // Sadece veriyi al (nesne dizisi) $satirlar = $repo->getSatirlar( raporad: 'satis_raporu', where: 'durum = :d', kosullar: [':d' => 'tamamlandi'] ); // HTML'i değişkene al $html = $renderer->renderRapor('satis_raporu'); echo '<div class="rapor">' . $html . '</div>';
Framework yok, Composer yok. Dosyaları indirin, SQL'i yükleyin, çalıştırın.
GitHub repo'sundan tüm dosyaları aynı klasöre koyun. Herhangi bir bağımlılık kurmanıza gerek yok.
kurulum.sql dosyasını phpMyAdmin'de import edin. Tablolar, view ve örnek veriler otomatik oluşur.
PDO nesnesini bir kez oluşturun ve Raporlar sınıfına iletin.
Tarayıcıda açın ve raporu görün. Örnek dosyalar hazır, hemen çalışır.
Eski kod birçok kritik güvenlik açığı barındırıyordu. Her biri sistematik olarak giderildi.