Web sitesi hazırlarken upload işlemlerinde gerekli önlemleri almazsak daha sonra istenmeyen sonuçlarla karşılaşabiliriz. Örneğin kötü niyetli birisi "hack.php" gibi bir dosyayı yükleyip çalıştırırsa web sitemizi hack edebilir. Veyahut geçerli bir resim dosyası olmadığı halde "resim.gif" gibi bir dosyayı yükleyebilir. Buna benzer problemlerin önüne geçmek için PHP diliyle bir upload sınıfı hazırladım.
Sınıfın en önemli özellikleri
Belirttiğiniz dosya türleri dışında dosyaların yüklenmesine izin vermez Yüklenen dosyalarda "resim" dosyaları varsa, her birinin gerçekten bir resim dosyası olup olmadığını otomatik olarak kontrol eder. Yüklenecek dosyaları istediğiniz klasöre kaydedebilirsiniz. Klasör yoksa sizin yerinize oluşturmayı dener ve "chmod" ayarını yapmaya çalışır. Aynı anda kaç adet dosyanın yükleneceğini ayarlayabilirsiniz. Örneğin; tek bir yükleme işleminde en az 5, en fazla 15 dosya yüklenebilsin gibi... Yüklenen dosyaların boyutlarını sınırlandırabilirsiniz. Örneğin; yüklenmek istenen herbir dosyanın boyutu en az 10, en fazla 100 KB olsun gibi... Yüklenen dosyaları yeniden isimlendirebilirsiniz. Ayrıca yüklenen her bir dosya için benzersiz isimler de oluşturabilirsiniz. Dosya isimlerinin başına veya sonuna bir ifade ekleyebilirsiniz. Bütün kotroller sunucunun "geçiçi" klasöründe yapılır. Herhangi bir sorun oluşmazsa, dosyaları istediğiniz klasöre taşıyabilirsiniz.
Sınıfın kullanımı
İlk önce upload işleminin yapılabilmesi için bir upload formu hazırlamamız gerekiyor. Alttaki kodlarla basit bir upload formu oluşturabiliriz.
<form method="post" action="yukle.php" enctype="multipart/form-data">
<input name="dosyalar[]" type="file" />
<input name="dosyalar[]" type="file" />
<input name="dosyalar[]" type="file" />
<button name="submit" type="submit">Yükle</button>
</form>
</body>
</html>
Yukarıdaki kodların ekran görüntüsü aşağıdaki resimdeki gibi görünecektir.
Bu upload formunu işlemek için eburhan Upload class'ı şöyle kullanabilirsiniz.
<?php
// sınıfı çağır
require_once('eb.upload.php');
// yüklenecek dosyalar varsa devreye gir
if( $_FILES )
{
// sınıfı hazırla
$up = new UPLOAD( $_FILES['dosyalar'] );
// yüklenecek dosyalar hangi klasöre kayıt edilecek
$up->yolDizin('./upload');
// 100 KB'a kadar olanlara izin ver
$up->maxBoyut(100);
// izin verilecek dosya türleri
$up->tipKabul('gif,jpg,png');
// yükleme işlemini başlat
if( $up->baslat() === FALSE ) {
} else {
echo 'Dosyalar başarıyla yüklendi';
}
}
?>
Yukarıdaki kodda yüklenmek istenen dosyaların upload isimli klasöre kaydedilmesini sağlıyoruz. Daha sonra herbir dosya boyutunun en fazla 100 KB olabileceğini ve sonra yüklenmek istenen dosyaların gif, jpg, png formatlarında olabileceğini belirtiyoruz.
Sonuç...
Hazırlamış olduğum eburhan Upload class sınıfının yetenekleri burada anlattığımla sınırlı değil. Daha fazla bilgi almak isteseniz alttaki bağlantıdan bu sınıfı indirebilirsiniz. İndireceğiniz dosya içerisinde ayrıntılı bir dökümantasyon mevcut. Bu dokümantasyon, sınıf hakkında merak ettiklerinize büyük bir ihtimal cevap verecektir. Yine de sormak istedikleriniz olursa bana istediğiniz zaman ulaşabilirsiniz 
öncelikle eline sağlık
ancak bir eksik var sanırım ya da ben işin içinden çıkamadım:
mesela izin verilen dosya tipleri rar,zip,jpg,gif olsun. bu durumda rar dosyaları da _imgKontrol’den geçiyor ve resim olmadığı için hata alıyor ve sonuçta hiç bir dosya yüklenmiyor…
Güzel hazırlanmış bir class. Teşekkürler.
@bocek
Uyarın için teşekkürler.
imgKontrol() fonksiyonuna gerekli kodları yazmayı unutmuşum (: Şimdi düzelttim.
Yeniden indirip test edersen sevinirim
Daha denemedim ama amacınızı buradan tebrik etmek istiyorum.
Ben sadece blog işiyle uğraştığım için işime yaramıyor ama güvenliği nasıl artırırım diyenler için faydalı bir yazı..
Türkçe bloglar arasında en faydalılardan birisi. Rüya tabiri, fıkra olmadan da ÅŸahane bir blog olabiliyormuÅŸ. Eline saÄŸlık…
Güzel olmuş ellerine sağlık fakat tür jpg veya gif ise resize ettirilebilirdi. ellerine sağlık tekrardan. benim ki fikir tabi oturup birtane de ben yazayım.
@Coder
Resim boyutlandırmayı bilerek eklemedim çünkü bu sınıfın görevi “yalnızca sunucuya dosya yüklemek” olsun istedim.
Ayrıca ben resim iÅŸlemleri için yine kendi yazdığım ayrı bir sınıf kullanıyorum. İleride yayınlarım belki. Ama siz bu upload sınıfını “miras alarak” resim boyutlandırma yeteneÄŸi kazandırabilirsiniz.
Teşekkurler Güzel çalışma
Açıkçası kendim yazacaktım php classısta arayim derken
Türk mucit yapıvermiş.
Merhaba, class’inizi kendi yazdigim bir icerik yönetim sisteminde kullaniyorum.
tipKabul() fonksiyonunda dosya uzantilari yerine mime-type’lara göre kontrol ettirseniz olmaz mi? Bazi resimlerin uzantilari resmin gercek tipinden farkli olabiliyor.
@Leon
Öncelikle class’ı kullandığın için teÅŸekkürler. Soruna gelince…
Mime-type ile kontrol ettirmek bana göre güvenli deÄŸildir. Çünkü bir dosyanın mime-type’ını kolayca deÄŸiÅŸtirebiliyorsun. Böylece olunca gerçekte PHP olan bir dosyayı PNG resmiymiÅŸ gibi yükletebilirsin.
Ayrıca bu class yüklenmek istenen dosyalardan hangilerinin gerçekten resim olup olmadığını kendisi otomatik olarak kontrol ediyor. Senin ekstra birşey yapmana gerek yok yani
peki bu upload’dan sonra linki falan nasıl göstercez onları da yazsaydın keÅŸke.
@YuqseLx
Ne linki acaba? Biraz daha açıklayıcı yazarsan sevinirim.
yani upload ettikten sonra resmin gösterim ÅŸekilleri imageshack.us’taki gibi
Hocam güzel bir class olmuş demin kullandım bir işimde. yanlız, bu upload edilen dosyanın adını nasıl alabiliriz, böyle bir imkanımız olabilir mi ?
2 ufak hata bildirmek istiyorum:
1. _dosyaIsmiTemizle() fonksiyonunda “ü” ve “Ü” harfleri “u” harfi yerine “y” harfine dönüştürülüyor. klavyede “u” ve “y” yanyana olduÄŸu için bir hata yapılmış sanırım.
2. yine _dosyaIsmiTemizle() fonksiyonunda “$onlyName” deÄŸiÅŸkeni ile ilgili bir sorun var. EÄŸer yüklemek istediÄŸim dosyanın uzantısı, dosya isminde de geçiyorsa sorun oluÅŸuyor. ÖrneÄŸin: “bu.bir.jpg.dosyası.jpg” isminde bir resim yüklemek istersem “bu_bir.jpg” ÅŸekline dönüşüyor. Çünkü “$onlyName” explode() ile bulunuyor ve bu da bu çeÅŸit bir hataya sebep oluyor.
Çok güzel bir class olduğunu belirtmek isterim
$up->yeniAd();
bu fonksiyonu dizi halinde çalıştırmak isterseniz
class yapısında fonksiyonda else parametresindeki $ad kısmına [$i] demek yeterli oluyo bunu farkettim paylaşmak istedim ellerine sağlık.
Yorumlarınızın hepsini not ettim. Birkaç gün içerisinde yeni bir güncelleme yayınlayacağım. Class’ı kullandığınız için teÅŸekkürler
Selamlar,
Kontroller için Erişim kontrol listesi tarzında yapsan daha hoş olurdu..
@Onur Yerlikaya
Nasıl mesela? Bir örnek gösterebilir misin?
Öncelikle çok güzel ve düzenli kodlanmış bu sınıfı yazdığınız için çok çok teşekkürler. Ufak bir önerim olacak:
Dosya tür kontrollerinde uzantılardan ziyade MIME tür kontrolü baz alınsa daha iyi olur gibime geliyor, biliyorum resim dosyaları için bu yapılmış durumda zaten ama bilinen sıkça kullanılan dosya türleri için de bu tip kontrol desteklense daha iyi olur kanımca…
Saygılarımla…
Çok güzel bir çalışma gerçekten ellerinize ve gözlerinize sağlık.
Fakat benim sormak istediÄŸim birÅŸey var. Bu sınıfınızı jquery’nin ajax fonksiyonu ile kullanmak istediÄŸimde formu serialize yaptığım zaman ne yazık ki dosya bilgileri hariç bütün bilgileri alabiliyorum formdan. Çözüm için bir öneriniz var mı acaba? Ne yazık ki basit bir çözüm bulamadım.
@tmrtzcn
Ajax ile dosya gönderirken farklı bir yol izlemen gerekiyor. Aşağıdaki linkten bu konuda bilgi alabilirsin.
http://ajax-tr.com/ajax-ile-dosya-gondermek/
peki bir sunucudan kendi sunucumuza dosya çekmek istersek nasıl olacak ? nasıl yapabiliriz ?
@ahmet
sunucudaki bir dosyayı kaydetmek için php’nin yerleÅŸik “file_get_contents” fonksiyonunu kullanabilirsin. Veya cURL eklentisi etkinse onu da kullanabilirsin. Åžurada örnek bir kod var.
güzel düşünülmüş ve yazılmış bir sınıf. Kodlama stilide oldukça hoş.. Yanlız benim bir sorunum oldu.
function VideoUpload()
{
global $videodosyasi;
$up = new eb_UPLOAD( $_FILES['video'] );
$up->yolDizin(’../../xvideo’);
$up->minDosya(1);
$up->tipKabul(’gif, jpg, png, wma, flv, swf, mp3, avi, mpeg’);
if( $up->baslat() === FALSE ) {
echo $up->sonHata();
} else {
$videodosyasi = $up->yeniAd();
//echo ‘Dosyalar baÅŸarıyla yüklendi’;
} $up->maxBoyut(100000000);
}
biçiminde kullandım. Küçük boyutlu dosyalarda herhangi bir sorun yaşamazken 10 mb civarı örneğin flv dosyalarda upload gerçekleşmiyor. İşlemi lokal sunucuda yapıyorum. Yani web üzerinde de değil. Sebebi ne olabilir ?
öncelikle s.a @eburhan paylaşımın gerçekten güzel ellerine sağlık bir yerde takıldım sormam gerekiyor;
“var $_bilgiVer = array();”
burada yüklendikten sonra array olarak veriyor bunun diğer yolları var mı alt alta yazması gibi ?
@cemaliozan
php.ini dosyasında upload_max_filesize ayarı vardır. Upload edilebilecek maksimum dosya boyutunu belirler. Ve bu ayar varsayılan olarak 2 MB deÄŸeriyle çalışır. O yüzden 2 MB’ı aÅŸan dosyaları upload edememeniz doÄŸal.
@YuqseLx
alt alta yazdırmak için foreach döngüsü kullanabilirsin. Örnek:
Bu şekilde upload edilmiş dosyanın bilgilerini alt alta yazdırabilirsin.
çok teşekkür ederim
Bence bu upload class ı biraz daha geliştirip jQuery için bir plugins haline getirmelisin. Ellerine sağlık gerçekten çok güzel olmuş.
Elinize sağlık. Benimde kafama taklıan bir kısım oldu. Bu izin verilen dosyaları upload etmesinde dosyaların uzantılarına bakıyor, bu yüzden birisi bir başka dosyanın uzantısını değiştirerek upload edilmesini sağlayabilir. Bu yüzden dosyanın adındaki uzantıya değilde, $_FILES['type'] üzerinden tipi tam belirlense daha makbul olur.
Bu güzel sınıf için öncelikle teşekkür ederim.
Wordpress için bir resim gönderme eklentisi yazmayı düşünüyorum. Eklentide sizin sınıfınızı kullanarak resmi upload etmeyi ardından bunu e-posta olarak kendime yollatmayı düşünüyorum.
Bunu yaparken dosyayı ismini $up->yeniAd( true ); fonksiyonu ile rastgele belirliyorum, maksimum dosya adedini 1 olarak ayarladım, dosya boyutunu 300 KB’de sınırladım, dosya tipi olarak jpg ve jpeg sınırı koydum, e-posta ile resmi yolladıktan sonra da dosyayı siliyorum, ayrıca dosyanın mime type’ının image/jpeg olduÄŸunu kontrol ediyorum.
Açıkçası güvenlik endişesi taşıyorum. Sizce güvenlik için yapabileceğim başka birşeyler var mı? Gelen resim e-posta içerisinde gösteriliyor, eğer uzantısı değiştirilmiş (bir zip dosyasının uzantısını .jpg yaptım) bir dosyayı yolladığımda hotmail resmi göstermiyor.
Başka yapabileceğim bir şey var mı?
@Yakup GÖVLER
Upload sırasında gerçekleşen işlemlere bakalım:
1. dosya uzantısı kontrol ediliyor
2. içerik türünü kontrol ediliyor (bunu siz yaptığınızı söylediniz)
3. sınıf içerisinde getimagesize() ile dosyanın resim dosyası olup olmadığına bakılıyor
Åžimdi bu 3 koÅŸulu aynı anda kontrol ettiÄŸimiz için güvenlik konusunda şüphelenmenize gerek yok diye düşünüyorum. Çünkü bu koÅŸullardan birisi atlatılsa bile mutlaka diÄŸerine yakalanılacaktır. İçerik türünü deÄŸiÅŸtirseniz getimagesize() fonksiyonu false verecek, resim dosyası içerisine kod enjekte etseniz bu sefer kodun çalışması için uzantısının php olması gerekecek, falan filan…
Yine de GD kütüphanesini kullanma şansınız varsa, bir de onunla imaj geçerliliğini daha sağlam bir şekilde test edebilirsiniz. Ama dediğim gibi üstteki 3 koşulu birlikte kontrol ettirdiğimizde buna bile gerek kalmaz. Bunların dışında aklıma şimdilik ek bir yöntem gelmiyor.
eklentiden sonradan haberim oldu
inceliyorum. teşekkürler