PHP ile Çoklu Dosya Yükleme İçin Güvenli Sürükle Bırak Arayüzü Nasıl Yapılır?
Modern web uygulamalarında kullanıcı deneyimini iyileştiren en önemli özelliklerden biri, dosyaları sürükle ve bırak yöntemiyle sunucuya gönderebilmektir. PHP ile çoklu dosya yükleme için güvenli sürükle bırak arayüzü oluşturmak, hem istemci tarafında JavaScript API'lerini hem de sunucu tarafında PHP'nin dosya işleme mekanizmalarını doğru yapılandırmayı gerektirir.
Bu rehberde, 2026 standartlarına uygun olarak, kullanıcıların dosyaları tarayıcıya sürükleyip bırakabileceği, arka planda asenkron (sayfa yenilenmeden) çalışan ve güvenlik önlemleri alınmış bir dosya yükleme sistemini adım adım inşa edeceğiz. Bu eğitim, orta seviye PHP bilgisine sahip geliştiriciler için tasarlanmıştır.
Gereksinimler ve Ön Hazırlık
Bu projeyi hayata geçirmek için modern bir web sunucusu ortamına ihtiyacınız vardır. Önerilen yapılandırma aşağıdadır:
- PHP 8.3 veya üzeri: Performans ve tip güvenliği için güncel sürüm zorunludur.
- Modern Bir Tarayıcı: HTML5 File API ve FormData desteği olan tüm tarayıcılar.
- Dosya İzinleri: Sunucuda yükleme yapılacak dizinin "yazılabilir" (writeable) olması gerekir.
- PHP Konfigürasyonu:
php.inidosyanızdaupload_max_filesizevepost_max_sizedeğerlerinin ihtiyaçlarınıza uygun ayarlandığından emin olun.
Adım 1: HTML ve CSS ile Sürükle Bırak Alanı Oluşturma
Kullanıcının dosyaları bırakacağı görsel alanı oluşturmak için temel HTML yapısını kuracağız. Burada önemli olan, sürükleme olaylarını (drag events) yakalayacak bir kapsayıcı (container) oluşturmaktır.
Dosyaları buraya sürükleyin veya tıklayın
Bu kod bloğu, kullanıcıya etkileşimli bir alan sunar. multiple özelliği, kullanıcının aynı anda birden fazla dosya seçmesine olanak tanır.
Adım 2: JavaScript ile Dosya Yakalama ve Asenkron Gönderim
Sürüklenen dosyaları yakalamak ve AJAX (Fetch API) kullanarak PHP sunucusuna göndermek için JavaScript kullanacağız. Bu yöntem, sayfa yenilenmeden yükleme yapılmasını sağlar.
const dropZone = document.getElementById('drop-zone');
dropZone.addEventListener('drop', (e) => {
e.preventDefault();
const files = e.dataTransfer.files;
uploadFiles(files);
});
function uploadFiles(files) {
const formData = new FormData();
for (let i = 0; i < files.length; i++) {
formData.append('files[]', files[i]);
}
fetch('upload.php', {
method: 'POST',
body: formData
}).then(response => response.json()).then(data => console.log(data));
}
Yukarıdaki kod, drop olayını dinler ve dosyaları FormData nesnesine ekleyerek upload.php dosyasına gönderir.
Adım 3: PHP Tarafında Dosya Güvenliği ve Doğrulama
Sunucu tarafında güvenlik en kritik konudur. Asla kullanıcıdan gelen dosya ismine güvenmeyin ve dosya türünü mutlaka kontrol edin.
Bu kod, dosya türünü mime_content_type ile doğrular ve uniqid() kullanarak dosya ismini rastgele hale getirir. Bu, aynı isimli dosyaların üzerine yazılmasını ve potansiyel zararlı scriptlerin çalıştırılmasını önler.
Adım 4: Güvenli Dosya Yükleme Karşılaştırma Tablosu
Dosya yükleme yöntemlerini ve güvenlik seviyelerini aşağıdaki tabloda karşılaştırdık:
| Yöntem | Güvenlik Seviyesi | Kullanıcı Deneyimi |
|---|---|---|
| Klasik Form (Input) | Orta | Düşük |
| Sürükle-Bırak (JS + PHP) | Yüksek (Doğru Filtreleme ile) | Çok Yüksek |
| Üçüncü Parti Kütüphaneler | Değişken | Yüksek |
Adım 5: Kritik Güvenlik Önlemleri
Dikkat: Kullanıcı tarafından yüklenen dosyaları asla doğrudan web kök dizininde (public_html) çalıştırmayın. Yükleme klasörüne bir
.htaccessdosyası ekleyerek PHP dosyalarının çalışmasını engelleyin:php_flag engine off. Ayrıca, dosya boyutunuupload_max_filesizeile sınırlamayı unutmayın.
Adım 6: Hata Ayıklama ve Test Etme
Sisteminizi test ederken tarayıcı konsolunu (F12) ve sunucu hata günlüklerini (error logs) sürekli kontrol edin. Yaygın hatalar şunlardır:
- İzin Hataları:
chmod 755veya775ile klasör izinlerini kontrol edin. - Boyut Sınırı: Yüklenen dosya
post_max_sizedeğerini aşıyorsa$_FILESdizisi boş döner. - MIME Tipi: Bazı sunucularda
mime_content_typeeksik olabilir, alternatif olarakfinfosınıfını kullanın.
$finfo = new finfo(FILEINFO_MIME_TYPE);
$mime = $finfo->file($tmpName);
Bu yöntem, dosya içeriğini daha güvenilir bir şekilde analiz eder.
Sıkça Sorulan Sorular
Dosyaları neden yeniden isimlendirmeliyim?
Kullanıcının yüklediği dosya ismi "script.php" olabilir. Eğer bunu olduğu gibi kaydederseniz, saldırganlar sunucunuzda kod çalıştırabilir. Rastgele isimler bu riski ortadan kaldırır.
Sürükle bırak arayüzü mobil cihazlarda çalışır mı?
Düz sürükle-bırak masaüstü için optimize edilmiştir. Mobil cihazlar için input type="file" öğesini gizleyip, tıklama olayını tetikleyen bir "Dosya Seç" butonu eklemek en iyi pratiktir.
Yüklenen dosyaları veritabanında mı tutmalıyım?
Dosyaları dosya sisteminde tutmalı, veritabanında ise sadece dosya yolunu (path) saklamalısınız. Büyük dosyaları veritabanına kaydetmek veritabanı performansını ciddi şekilde düşürür.
Aynı anda yükleme sınırı nasıl konur?
JavaScript tarafında files.length kontrolü yaparak, PHP tarafında ise döngü içerisinde bir sayaç kullanarak yükleme sınırını kolayca belirleyebilirsiniz.
Büyük dosyalar için ne yapmalıyım?
Dosyaları "chunking" (parçalara bölme) yöntemiyle yüklemelisiniz. 2026 standartlarında, 50MB üzerindeki dosyalar için bu yöntem zorunludur.
Yasal Uyarı: Bu rehberdeki kodlar eğitim amaçlıdır. Üretim ortamında kullanmadan önce dosya içeriği tarama (antivirus scanning), dosya boyutu kısıtlamaları ve yetkilendirme kontrollerini kendi güvenlik politikalarınıza göre güncelleyiniz.
İleri Seviye İpuçları: Dosya İşleme Süreçlerinde Performans Optimizasyonu
Dosya yükleme işlemlerinde performans, özellikle eşzamanlı kullanıcı sayısının yüksek olduğu projelerde kritik bir rol oynar. Sunucu kaynaklarını verimli kullanmak ve kullanıcıya kesintisiz bir deneyim sunmak için aşağıdaki optimizasyon stratejilerini uygulayabilirsiniz.
PHP ve Nginx/Apache Yapılandırması
PHP tarafında kodunuz ne kadar güvenli olursa olsun, sunucu yapılandırmanız yanlışsa büyük dosyalar yüklenirken "413 Request Entity Too Large" hatası alırsınız. php.ini dosyanızda şu ayarları projenizin ihtiyaçlarına göre güncellediğinizden emin olun:
; php.ini ayarları
upload_max_filesize = 64M
post_max_size = 64M
max_execution_time = 300
memory_limit = 256M
Ayrıca, Nginx kullanıyorsanız nginx.conf dosyasında client_max_body_size 64M; direktifini eklemeyi unutmayın. Aksi takdirde PHP'ye istek ulaşmadan sunucu bağlantıyı kesecektir.
Dosya İşleme İçin Kuyruk (Queue) Kullanımı
Kullanıcı dosyayı yüklediği anda sunucu üzerinde resim boyutlandırma, PDF sıkıştırma veya virüs taraması gibi ağır işlemler yapıyorsanız, bu süreçler HTTP isteğini bekletecektir. Bunun yerine, dosyayı güvenli bir geçici klasöre alıp, işleme sürecini bir kuyruk sistemine (örneğin Redis veya RabbitMQ) devretmek en iyi pratiktir.
Basit bir kuyruk mantığı şu şekilde işler:
- Dosya yüklenir ve doğrulanır.
- Dosya bilgileri veritabanına "beklemede" statüsüyle kaydedilir.
- Bir arka plan işçisi (worker) veritabanındaki kayıtları sırayla işler.
- İşlem tamamlandığında dosya statüsü "tamamlandı" olarak güncellenir.
Alternatif Kütüphaneler ve Modern Yaklaşımlar
Sıfırdan bir sürükle-bırak arayüzü yazmak öğretici olsa da, üretim ortamında (production) dosya yükleme süreçlerini yönetmek için kanıtlanmış kütüphaneleri kullanmak hata payını düşürür. Özellikle büyük ölçekli uygulamalarda şu araçlar standart kabul edilir:
- Uppy.io: Sürükle-bırak, kamera desteği ve AWS S3 entegrasyonu ile gelen en popüler modüler kütüphanedir.
- Dropzone.js: Hafif ve özelleştirilebilir yapısıyla hızlı entegrasyon için idealdir.
- Fine Uploader: Özellikle eski tarayıcı desteği ve parçalı yükleme (chunking) konusunda oldukça başarılıdır.
Parçalı Yükleme (Chunked Uploads) Mantığı
50MB üzerindeki dosyalar için tarayıcıyı tek seferde zorlamak yerine, dosyayı küçük parçalara (örneğin 1MB'lık parçalar) bölerek yüklemek, bağlantı kopmalarında tüm yüklemenin iptal olmasını engeller. Aşağıdaki örnek, JavaScript ile dosyanın nasıl parçalara ayrılacağını gösterir:
// Basit bir parçalı yükleme mantığı
const file = document.getElementById('fileInput').files[0];
const chunkSize = 1024 * 1024; // 1MB
let offset = 0;
function uploadChunk(file, offset) {
const chunk = file.slice(offset, offset + chunkSize);
const formData = new FormData();
formData.append('file', chunk);
formData.append('filename', file.name);
fetch('upload.php', {
method: 'POST',
body: formData
}).then(() => {
offset += chunkSize;
if (offset < file.size) {
uploadChunk(file, offset);
} else {
console.log("Yükleme tamamlandı!");
}
});
}
Bu yöntemle, sunucu tarafında file_put_contents($path, $data, FILE_APPEND) fonksiyonunu kullanarak parçaları birleştirebilir ve çok daha kararlı bir dosya transfer süreci elde edebilirsiniz.
Sonuç
PHP ile çoklu dosya yükleme için güvenli sürükle bırak arayüzü oluşturmak, hem kullanıcı deneyimini hem de sistem güvenliğini bir üst seviyeye taşır. Bu rehberdeki adımları takip ederek, modern ve güvenli bir yükleme mekanizması kurabilirsiniz. Bir sonraki adım olarak, yüklenen dosyaları bir "Cloud Storage" (örneğin AWS S3) üzerinde saklamayı ve dosya yükleme süreçlerini kuyruk (queue) sistemleri ile yönetmeyi araştırabilirsiniz.


Yorumlar (0)
Yorum Yaz