Php İle Nesne Yönelimli Yapıda Çoklu Dosya Yükleme Sistemi Nasıl Yapılır?

Php İle Nesne Yönelimli Yapıda Çoklu Dosya Yükleme Sistemi Nasıl Yapılır?
Php İle Nesne Yönelimli Yapıda Çoklu Dosya Yükleme Sistemi Nasıl Yapılır?

Gereksinimler ve Ön Hazırlık

Bu projeyi başarılı bir şekilde hayata geçirebilmek için bilgisayarınızda PHP 8.2 veya üzeri bir sürümün kurulu olması gerekmektedir. Modern PHP sürümleri, tip tanımlamaları (type hinting) ve hata yönetimi konusunda çok daha güvenli araçlar sunar.

  • PHP 8.2+ kurulu bir web sunucusu (Apache veya Nginx).
  • Dosya yazma izinlerine sahip bir "uploads" dizini.
  • Temel düzeyde HTML5 form yapısı bilgisi.
  • Dosya yükleme limitlerini kontrol etmek için php.ini üzerinde upload_max_filesize ve post_max_size ayarlarının düzenlenmiş olması.

HTML Form Yapısının Oluşturulması

Çoklu dosya yükleme işleminin ilk adımı, HTML formunda multiple niteliğini kullanmak ve name parametresini bir dizi (array) şeklinde tanımlamaktır. Bu, PHP tarafında verilerin bir dizi olarak karşılanmasını sağlar.


    Dosyaları Seçin:
    
    Yükle

Burada dikkat etmeniz gereken en önemli nokta enctype="multipart/form-data" özelliğidir. Bu özellik olmadan, form verileri sunucuya gönderilse bile dosyalar taşınamaz. name="dosyalar[]" kullanımı ise, PHP'nin bu veriyi bir dizi olarak işlemesine olanak tanır.

Dosya Yükleme Sınıfının Tasarlanması

Nesne yönelimli yapıda bir sınıf oluştururken, dosya yükleme mantığını izole etmeliyiz. Aşağıdaki FileUploader sınıfı, dosyaları kontrol eder, doğrular ve belirtilen dizine taşır.

class FileUploader {
    private string $uploadDir;
    private array $allowedTypes = ['image/jpeg', 'image/png', 'application/pdf'];
    private int $maxSize = 2097152; // 2MB

    public function __construct(string $uploadDir) {
        $this->uploadDir = rtrim($uploadDir, '/') . '/';
    }

    public function upload(array $file): bool {
        if ($file['error'] !== UPLOAD_ERR_OK) return false;
        if ($file['size'] > $this->maxSize) return false;
        if (!in_array($file['type'], $this->allowedTypes)) return false;

        $fileName = uniqid() . '_' . basename($file['name']);
        return move_uploaded_file($file['tmp_name'], $this->uploadDir . $fileName);
    }
}

Bu sınıf, uploadDir değişkeni ile hedef klasörü belirler. upload metodu ise dosyanın hata kodunu, boyutunu ve MIME türünü kontrol ederek güvenlik katmanlarını oluşturur. uniqid() kullanımı, aynı isimli dosyaların üzerine yazılmasını engellemek için kritik bir yöntemdir.

Çoklu Dosyaların İşlenmesi

HTML formundan gelen $_FILES dizisi, tekli yüklemeden farklı bir yapıya sahiptir. Bu yapıyı düzgün bir şekilde döngüye alarak sınıfımızdaki upload metoduna göndermemiz gerekir.

$uploader = new FileUploader('uploads');

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['dosyalar'])) {
    $files = $_FILES['dosyalar'];
    $count = count($files['name']);

    for ($i = 0; $i < $count; $i++) {
        $file = [
            'name' => $files['name'][$i],
            'type' => $files['type'][$i],
            'tmp_name' => $files['tmp_name'][$i],
            'error' => $files['error'][$i],
            'size' => $files['size'][$i]
        ];
        $uploader->upload($file);
    }
}

Bu kod bloğu, $_FILES dizisini parçalayarak her bir dosyayı ayrı bir dizi haline getirir ve FileUploader sınıfına iletir. Böylece her dosya bağımsız olarak doğrulanır ve işlenir.

Güvenlik ve Hata Yönetimi Karşılaştırması

Dosya yükleme sistemlerinde kullanılan yöntemlerin karşılaştırmalı analizi aşağıdadır:

Yöntem Avantajı Dezavantajı
Doğrudan move_uploaded_file Hızlı ve basit Güvenlik açığı riski yüksek
OOP (Sınıf Yapısı) Modüler, güvenli, test edilebilir Daha fazla kod yazımı
Veritabanı Kayıtlı Sistem İzlenebilirlik sağlar Ekstra veritabanı yükü
Kritik Güvenlik Uyarısı: Dosya yükleme sistemlerinde asla kullanıcıdan gelen dosya ismine güvenmeyin. Her zaman basename() fonksiyonunu kullanın ve dosyaları web kök dizininin dışına veya isimlendirmeyi değiştirerek (örneğin uniqid() ile) kaydedin. Ayrıca, yüklenen dosyaların çalıştırılabilir (PHP, JS, vb.) olmadığından emin olmak için MIME türü kontrollerini asla atlamayın.

Sıkça Sorulan Sorular

Dosya yükleme limitini nasıl artırabilirim?

PHP'nin upload_max_filesize ve post_max_size değerlerini php.ini dosyanızdan güncelleyerek artırabilirsiniz. Değişiklik sonrası sunucuyu yeniden başlatmayı unutmayın.

Neden dosya isimlerini değiştiriyoruz?

Kullanıcıların yüklediği dosya isimleri özel karakterler içerebilir veya sunucudaki mevcut dosyalarla çakışabilir. Ayrıca, kötü niyetli kullanıcıların .php uzantılı dosyalar yükleyip sunucuyu ele geçirmesini engellemek için isimleri rastgele oluşturmak en güvenli yoldur.

Yüklenen dosyaların türünü nasıl kısıtlarım?

finfo_file() fonksiyonunu kullanarak dosyanın gerçek MIME türünü analiz edebilir ve sınıfınızdaki $allowedTypes dizisi ile karşılaştırabilirsiniz. Sadece $_FILES['type'] değerine güvenmek yanıltıcı olabilir.

Çok büyük dosyalar için ne yapmalıyım?

Çok büyük dosyalar için PHP'nin senkron yapısı yerine, parçalı yükleme (chunked upload) yapan JavaScript kütüphanelerini veya arka plan iş kuyruklarını (queue) tercih etmelisiniz.

Hata kodları ne anlama gelir?

UPLOAD_ERR_OK (0) başarılı demektir. UPLOAD_ERR_INI_SIZE (1) dosyanın php.ini limitini aştığını, UPLOAD_ERR_PARTIAL (3) ise dosyanın sadece bir kısmının yüklendiğini ifade eder.

İleri Düzey Dosya İşleme ve Performans Optimizasyonu

Çoklu dosya yükleme işlemlerinde sistemin performansını artırmak ve sunucu kaynaklarını verimli kullanmak, özellikle yüksek trafikli uygulamalar için kritiktir. Yüklenen dosyaların doğrudan sunucu diskine yazılması yerine, belirli bir iş akışıyla yönetilmesi gerekir.

Dosya Yükleme Sürecinde Bellek Yönetimi

PHP, varsayılan olarak upload_max_filesize ve post_max_size değerleri ile sınırlıdır. Ancak, çok sayıda büyük dosya yüklendiğinde bellek kullanımı hızla artabilir. Bu durumu yönetmek için yükleme işlemini parçalara ayırmak veya geçici dizinleri düzenli olarak temizlemek gerekir.

Aşağıdaki örnekte, yüklenen dosyaların boyutunu kontrol eden ve geçici dizini temizleyen bir yardımcı metot yapısını inceleyebilirsiniz:


public function optimizeUploadProcess($files) {
    $maxSize = 5 * 1024 * 1024; // 5MB limit
    foreach ($files['size'] as $size) {
        if ($size > $maxSize) {
            throw new Exception("Dosya boyutu limitin üzerinde.");
        }
    }
    // Geçici dizindeki eski dosyaları temizleme mantığı
    $tmpDir = sys_get_temp_dir();
    // ... temizleme işlemleri
}

Dosya Yükleme Sistemlerinde Hata Ayıklama (Debugging) Stratejileri

Geliştirme aşamasında karşılaşılan hataların çoğu, yanlış dizin izinlerinden veya yapılandırma dosyalarındaki çakışmalardan kaynaklanır. Hata ayıklama sürecini hızlandırmak için PHP'nin error_get_last() fonksiyonunu ve özel bir loglama mekanizmasını kullanmak en sağlıklı yöntemdir.

Loglama Mekanizması Kurulumu

Hataları kullanıcıya göstermek yerine bir log dosyasına yazmak, güvenlik açısından daha profesyonel bir yaklaşımdır. İşte basit bir hata loglama sınıfı entegrasyonu:


class FileLogger {
    public static function log($message) {
        $logEntry = "[" . date('Y-m-d H:i:s') . "] " . $message . PHP_EOL;
        file_put_contents('upload_errors.log', $logEntry, FILE_APPEND);
    }
}

// Kullanımı:
try {
    $uploader->upload();
} catch (Exception $e) {
    FileLogger::log($e->getMessage());
}

Test Senaryoları ve Deployment Öncesi Kontroller

Sisteminizi canlı ortama almadan önce mutlaka şu senaryoları test etmelisiniz:

  • MIME Tipi Kontrolü: Sadece uzantıya bakmak yerine, finfo_file kullanarak dosyanın gerçek içeriğini doğrulayın.
  • Dizin İzinleri: Yükleme klasörünün 755 veya 775 izinlerine sahip olduğundan, ancak yazılabilir olduğundan emin olun.
  • Dosya İsmi Çakışmaları: Aynı isimli iki dosya yüklendiğinde üzerine yazılmaması için uniqid() veya bin2hex(random_bytes(8)) gibi fonksiyonlarla benzersiz isimler türetin.
Önemli İpucu: Deployment aşamasında, yükleme dizininizi web kök dizininin (public_html) dışında tutarak, doğrudan dosya erişimini engelleyebilir ve güvenlik katmanını güçlendirebilirsiniz.

Sonuç

PHP ile nesne yönelimli yapıda çoklu dosya yükleme sistemi oluşturmak, projenizin profesyonellik seviyesini bir adım öteye taşır. Bu rehberde öğrendiğiniz sınıf tabanlı yaklaşım, kodunuzu daha temiz hale getirirken güvenlik açıklarını minimize etmenize yardımcı olur. Bir sonraki adım olarak, yüklenen dosyaların bilgilerini bir veritabanında saklayarak, dosya yönetimi panelinizi geliştirebilirsiniz.

Sorumluluk Reddi: Bu makalede yer alan kod örnekleri eğitim amaçlıdır. Uygulamanızı canlıya almadan önce, sunucu yapılandırmanızı, dosya izinlerini ve güvenlik duvarı ayarlarınızı (WAF) mutlaka kontrol edin. Yazılım güvenliği sürekli güncellenen bir süreçtir; her zaman en son güvenlik yamalarını takip edin.
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