Php İle Nesne Yönelimli Yapıda Dinamik Site İçi Veri Dışa Aktarma Nasıl Yapılır?

Php İle Nesne Yönelimli Yapıda Dinamik Site İçi Veri Dışa Aktarma Nasıl Yapılır?
Php İle Nesne Yönelimli Yapıda Dinamik Site İçi Veri Dışa Aktarma Nasıl Yapılır?

Ön Hazırlık ve Gereksinimler

Projeye başlamadan önce sisteminizde PHP 8.2 veya daha yeni bir sürümün yüklü olduğundan emin olmalısınız. Ayrıca veritabanı işlemleri için PDO (PHP Data Objects) kütüphanesinin aktif olması gerekmektedir. Veri dışa aktarma süreçlerinde bellek yönetimi kritik olduğu için memory_limit ayarlarınızın yeterli düzeyde olduğunu kontrol edin.

  • PHP 8.2+ sürümü.
  • PDO eklentisi aktif bir veritabanı sunucusu (MySQL/MariaDB).
  • Composer (isteğe bağlı, kütüphane bağımlılık yönetimi için).
  • Temel düzeyde OOP ve arayüz (Interface) bilgisi.

Veri Dışa Aktarma İçin Arayüz (Interface) Tasarımı

Nesne yönelimli yapıda esneklik sağlamak için öncelikle dışa aktarma stratejilerimizi tanımlayan bir arayüz oluşturmalıyız. Bu sayede gelecekte yeni formatlar (örneğin Excel veya PDF) eklemek istediğimizde mevcut yapıyı bozmadan genişletme yapabiliriz.

interface ExportableInterface {
    public function export(array $data): string;
}

Bu arayüz, her dışa aktarma sınıfının export metodunu zorunlu kılmasını sağlar. Bu sayede kodunuzda tip güvenliği (type-hinting) sağlayarak hataları minimize edersiniz.

CSV Formatında Veri Dışa Aktarma Sınıfı

Şimdi ExportableInterface kullanarak CSV formatı için somut bir sınıf oluşturalım. Bu sınıf, veriyi alıp uygun formatta bir string veya dosya akışı haline getirecektir.

class CsvExporter implements ExportableInterface {
    public function export(array $data): string {
        $output = fopen('php://temp', 'r+');
        foreach ($data as $row) {
            fputcsv($output, $row);
        }
        rewind($output);
        $csv = stream_get_contents($output);
        fclose($output);
        return $csv;
    }
}

Burada php://temp akışını kullanarak veriyi bellekte işliyoruz. Bu yöntem, büyük verilerde disk I/O yükünü azaltır ve performansı artırır.

Veritabanı Katmanı ve Veri Çekme İşlemi

Verileri veritabanından güvenli bir şekilde çekmek için PDO kullanmalıyız. SQL Injection saldırılarına karşı hazırlıklı olmak adına her zaman "prepared statements" (hazırlanmış ifadeler) kullanılması zorunludur.

class DataProvider {
    private PDO $db;

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

    public function fetchUsers(): array {
        $stmt = $this->db->query("SELECT id, username, email FROM users");
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }
}

Veritabanı bağlantınızı her zaman bir yapılandırma dosyası üzerinden yönetin ve veritabanı şifrelerinizi asla kaynak kod içerisinde açık bir şekilde bırakmayın.

Dinamik Dışa Aktarma Yöneticisi (Manager Class)

Şimdi tüm parçaları bir araya getiren bir yönetici sınıfı oluşturalım. Bu sınıf, bağımlılık enjeksiyonu (dependency injection) kullanarak hangi formatta dışa aktarma yapılacağını belirler.

class ExportManager {
    private ExportableInterface $exporter;

    public function __construct(ExportableInterface $exporter) {
        $this->exporter = $exporter;
    }

    public function download(array $data, string $filename): void {
        header('Content-Type: text/csv');
        header('Content-Disposition: attachment; filename="' . $filename . '"');
        echo $this->exporter->export($data);
        exit;
    }
}

Bu yapı, ExportManager sınıfının hangi formatta çıktı üreteceğinden bağımsız çalışmasını sağlar. Bu, kodun test edilebilirliğini (unit testing) ciddi oranda artırır.

Uygulama ve Kullanım Örneği

Tüm sınıfları birleştirerek bir dışa aktarma isteğini nasıl karşılayacağımızı görelim. Bu adım, sistemin uçtan uca nasıl çalıştığını gösterir.

try {
    $pdo = new PDO('mysql:host=localhost;dbname=test_db', 'user', 'pass');
    $provider = new DataProvider($pdo);
    $users = $provider->fetchUsers();

    $manager = new ExportManager(new CsvExporter());
    $manager->download($users, 'kullanicilar.csv');
} catch (Exception $e) {
    error_log($e->getMessage());
    echo "Bir hata oluştu.";
}

Bu kod bloğu, veritabanından veriyi çeker, CSV formatına dönüştürür ve kullanıcıya indirme başlığı ile sunar. Hata yönetimi için try-catch bloğu kullanmak, sistemin kararlılığı için kritiktir.

Karşılaştırma: Dışa Aktarma Yöntemleri

Format Avantajı Dezavantajı
CSV Hafif, Excel ile uyumlu Karmaşık ilişkisel verilerde zayıf
JSON API dostu, hiyerarşik yapı Büyük dosyalarda parse etmesi zor
XML Standart, şema desteği Dosya boyutu çok büyük olur

Kritik Güvenlik Uyarısı: Dışa aktarılan verilerin kullanıcı tarafından girilen içerikleri barındırdığı durumlarda, XSS (Cross-Site Scripting) riskine karşı verileri mutlaka temizleyin (sanitization). Ayrıca, dosya isimlerini kullanıcı girdisinden doğrudan almayın; rastgele bir isim veya sabit bir isim atayın.

Sıkça Sorulan Sorular

Dışa aktarma sırasında bellek hatası alıyorum, ne yapmalıyım?

Büyük veri setlerinde fetchAll() kullanmak yerine PDOStatement üzerinde döngü kurarak veriyi parça parça (chunk) okuyup çıktıya basmalısınız.

Neden Interface kullanmalıyım?

Interface kullanımı, kodunuzun "Open/Closed" prensibine uygun olmasını sağlar. Yani kodunuz gelişime açık, değişime kapalı olur.

JSON dışa aktarmayı nasıl eklerim?

ExportableInterface uygulayan yeni bir JsonExporter sınıfı yazmanız ve json_encode fonksiyonunu kullanmanız yeterlidir.

Veri güvenliğini nasıl sağlarım?

Veritabanı sorgularında her zaman prepared statements kullanın ve kullanıcıya sunulan dosya içeriğini çıktı almadan önce filtreleyin.

Üretim ortamında (production) nelere dikkat etmeliyim?

Hata raporlamasını (display_errors) kapatın ve veritabanı bağlantı bilgilerini environment (çevre) değişkenlerinde saklayın.

Büyük Veri Setleri İçin Bellek Yönetimi ve Stream (Akış) Kullanımı

Dışa aktarılacak veri setleri binlerce satıra ulaştığında, tüm veriyi belleğe (RAM) yüklemek sunucunun "Memory Limit" hatası almasına neden olur. Bu durumu engellemek için PHP'nin php://output akışını ve veritabanı sorgularında yield anahtar kelimesini kullanarak "Generator" yapısını kullanmalısınız.

Aşağıdaki örnekte, veritabanından verileri tek tek çekerek belleği yormadan dışa aktaran bir yapı görebilirsiniz:


class StreamExporter {
    public function exportToCsv(iterable $data, string $filename) {
        header('Content-Type: text/csv');
        header('Content-Disposition: attachment; filename="' . $filename . '"');

        $output = fopen('php://output', 'w');
        foreach ($data as $row) {
            fputcsv($output, $row);
        }
        fclose($output);
        exit;
    }
}

// Veritabanından veriyi Generator ile çekme
function fetchLargeData($pdo) {
    $stmt = $pdo->query("SELECT * FROM users");
    while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
        yield $row;
    }
}

Dışa Aktarma Süreçlerinde Birim Test (Unit Testing) Yazımı

Dışa aktarma sınıflarınızın doğruluğunu garanti altına almak için PHPUnit kullanarak testler yazmak, projenin sürdürülebilirliği için kritiktir. Özellikle CSV çıktısının formatının bozulup bozulmadığını kontrol eden testler, refactoring (kod iyileştirme) süreçlerinde hayat kurtarır.

Örnek bir test senaryosu şu şekildedir:


use PHPUnit\Framework\TestCase;

class ExporterTest extends TestCase {
    public function testCsvFormatIsCorrect() {
        $exporter = new CsvExporter();
        $data = [['id' => 1, 'name' => 'Test Kullanıcı']];
        
        $result = $exporter->format($data);
        
        $this->assertStringContainsString('1,Test Kullanıcı', $result);
    }
}

Test Edilebilir Kod İçin İpuçları

  • Dependency Injection: Veritabanı bağlantılarını sınıfların içine doğrudan yazmak yerine constructor üzerinden enjekte edin.
  • Mocking: Veritabanı bağlantısını test ederken gerçek veritabanına bağlanmak yerine, veritabanı arayüzünü (Interface) mock'layarak test sürenizi kısaltın.
  • Edge Cases: Boş veri seti, hatalı karakter içeren veriler ve çok uzun metin alanları için özel test senaryoları oluşturun.

Performans İzleme ve Loglama

Dışa aktarma işlemleri genellikle arka planda uzun süren süreçlerdir. Kullanıcıların bu süreci takip edebilmesi veya hata durumunda müdahale edilebilmesi için işlem loglarını tutmak önemlidir. İşlem süresini ve dışa aktarılan toplam satır sayısını kaydederek sistem performansınızı analiz edebilirsiniz.


class ExportLogger {
    public function logProcess(string $format, int $rowCount, float $startTime) {
        $duration = microtime(true) - $startTime;
        $message = sprintf("[%s] Format: %s | Satır: %d | Süre: %.2f sn\n", 
            date('Y-m-d H:i:s'), $format, $rowCount, $duration);
        
        file_put_contents('export_logs.txt', $message, FILE_APPEND);
    }
}

Sonuç

PHP ile nesne yönelimli yapıda veri dışa aktarma, doğru mimari ile oldukça basit ve güvenli bir süreçtir. Arayüzler ve bağımlılık enjeksiyonu kullanarak, projenizin gelecekteki ihtiyaçlarına göre kolayca genişletilebilir bir yapı kurmuş oldunuz. Bir sonraki adım olarak, bu sisteme bir "Excel" dışa aktarma sınıfı ekleyerek PhpSpreadsheet kütüphanesini entegre etmeyi deneyebilirsiniz.

Sorumluluk Reddi: Bu rehberdeki kod örnekleri eğitim amaçlıdır. Üretim ortamına almadan önce veritabanı bağlantı güvenliğini (SSL/TLS) ve sunucu izinlerini mutlaka kontrol edin. Yazılım güvenliği, sürekli güncellenen bir süreçtir; kütüphanelerinizi ve PHP sürümünüzü her zaman güncel tutun.

Bu yazıya tepkinizi paylaşın:
Mert Çelik

Teknoloji dünyasını ve dijital araçları günlük hayata entegre etme konusunda içerikler üretiyorum. Karmaşık teknik rehberleri en yalın haliyle sunmayı hedefliyorum.

Yorumlar (0)

Yorum Yaz