RSS

PHP ile dosya upload

52 16 Haziran 2010 ~ Musa Avcı — Orta

PHP dosya yükleme işleme için önceki derslerde öğrendiğimiz html formunu kullanacağız. Başkalarının bilgisayarında olan dosyaları kendi sunucumuza göndereceğimiz bu çalışmada güvenlik için biraz dikkatli ve tedbirli olmamız gerekiyor.

Eğer hiç bir koşul uygulamadan saf bir upload uygulaması yapacak olursak, isteyen herkes sitemize istediği dosyayı ve yazılımı gönderebilir, kendi kodlarını atıp sitemizi ele geçirebilir.

Bunun için dosyaları enine boyuna kontrol edip onayladıktan sonra sitemize göndereceğiz. Öncelikle dosya uzantısına, dosya boyutuna ve dosyanın tipine bakacağız. Tipini ya da boyunu beğenmezsek almayacağız.

PHP upload formu hazırlama

Bunun için başta da dediğim gibi önceden anlattığımız html formunu kullanacağız. Ve bu formda gönderilecek dosyayı seçmemizi sağlayacak olan file form elementini yerleştireceğiz. Bir de form etiketine enctype değerine dosya upload edeceğimiz için “multipart/form-data” parametresini ekleyeceğiz.

<form action="gonder.php" method="post" enctype="multipart/form-data">
   <input type="file" name="dosya" />
   <input type="submit" value="Gönder" />
</form>

Bu formu tarayıcımızdan açtığımızda aşağıdaki gibi bir görüntü meydana gelmiş olacak. Ve gönder butonuna bastığımızda da dosyayı action parametresinde belirttiğimiz gonder.php sayfasına gönderecek.

Oluşturduğumuz bu form ile artık kullanıcılardan bize dosya transfer etme yolunu kurmuş olduk.

PHP’ye gönderilen dosyaları kontrol edip yüklemek

Şimdi gelelim dosyaların gönderileceği uygulamamıza, yani bizim örnekte gonder.php olarak adlandırdığımız sayfamıza.

İlk olarak sayfamıza bir dosya gönderilmiş mi diye kontrol edeceğiz. Eğer sayfaya direkt girmeye çalışılırsa hiç bir şey yapmamamız gerekiyor. Sonrasında $_FILES global değişkenini kullanarak bize gönderilen dosyanın boyutuna, tipine ve uzantılarına bakacağız.

Yine isset fonksiyonunu kullanarak bir dosya gönderilmiş mi diye bakacağız. Eğer gönderilmiş ise $_FILES global dizininde gönderilen dosya elementinin adında bir dizin oluşmuş olur. Yani form elementininin name parametresine yazdığımız isimimi kullanacağız. Biz formumuzu yaparken bu değere “dosya” yazmıştık.

if(isset($_FILES['dosya'])) {
   echo 'Dosya gönderilmiş';
} else {
   echo 'Lütfen bir dosya gönderin';
}

Bu örnekte yanlızca sayfaya bir upload yapılmış mı diye kontrol ettik. Şimdi eğer dosya gönderilmişse boyutuna ve tipine bakma sırasında.

Bunlar için $_FILES global dizininin bizim dosyamız için ürettiği diğer alt dizin değerlerine bakacağız, bunları bir tabloda gösterelim.

İsim Açıklama
name Gönderilen dosyanın adı
type Gönderilen dosyanın tipi
tmp_name Gönderilen dosyanın geçici olarak sunucuda barındığı adres.
size Gönderilen dosyanın bayt cinsinden boyutu
error Dosya gönderilirken gerçekleşen hata kodu

Yukarıdaki değerleri $_FILES global dizininde kendi dosya elementi adımızı girdikten sonra alt dizin şeklinde erişeceğiz.

if(isset($_FILES['dosya'])){
   $hata = $_FILES['dosya']['error'];
   if($hata != 0) {
      echo 'Yüklenirken bir hata gerçekleşmiş.';
   } else {
      $boyut = $_FILES['dosya']['size'];
      if($boyut > (1024*1024*3)){
         echo 'Dosya 3MB den büyük olamaz.';
      } else {
         $tip = $_FILES['dosya']['type'];
         $isim = $_FILES['dosya']['name'];
         $uzanti = explode('.', $isim);
         $uzanti = $uzanti[count($uzanti)-1];
         if($tip != 'image/jpeg' || $uzanti != 'jpg') {
            echo 'Yanlızca JPG dosyaları gönderebilirsiniz.';
         } else {
            $dosya = $_FILES['dosya']['tmp_name'];
            copy($dosya, 'dosyalar/' . $_FILES['dosya']['name']);
            echo 'Dosyanız upload edildi!';
         }
      }
   }
}

Evet farkındayım çok uzun ve karışık görünen bir kod oldu ama koşulları yukarıdan aşağıya doğru incelerseniz aslında gayet düzenli bir şekilde kontrol ettik ve en sonunda tüm koşulları geçtiyse copy() fonksiyonu ile dosyayı geçici dizinden alıp dosyalar dizinine gönderdik.

Sırayla anlatayım. İlk olarak 1. satırda isset() fonksiyonu ile sayfaya gönderilme işlemi yapılıp yapılmadığına baktık.

2. ve 3. satırlarda gönderilen dosya bilgilerinden error değerine bakarak dosya gönderilmesinde herhangi bir hata meydana gelmiş mi diye kontrol ettik. Eğer error değeri 0 ise bir hata meydana gelmemiş demek olur. Bu hataların sebebi daha önceden de bahsettiğimiz gibi yazma izni gibi şeylerden ötürü kaynaklanabilir.

$hata = $_FILES['dosya']['error'];
if($hata != 0) {
  echo 'Yüklenirken bir hata gerçekleşmiş.';
} else {
// ...

6. ve 7. satırlarda size değeri ile dosyanın boyutunu alıp (1024*1024*3) den büyük olup olmadığına baktık. Bu hesabın sonucu 3MB‘nin bayt cinsinden değerini verir. Eğer 3MB den büyük ise kabul etme demiş olduk.

$boyut = $_FILES['dosya']['size'];
if($boyut > (1024*1024*3)){
   echo 'Dosya 3MB den büyük olamaz.';
} else {
// ...

10 – 15 satırları arasında dosyanın tipinin ne olduğuna ve dosyanın uzantısına baktık. Burada ben örnek olarak “image/jpeg” tipini ve jpg uzantısını kullandım, sen hangi dosyalara izin veriyorsan ona göre yanlızca uzantıları ya da tipleri kullanabilirsin. Örneğin $uzanti == ‘jpg’ || $uzanti == ‘gif’ || $uzanti == ‘png’ diyerek yanlızca bu üç uzantılı dosyaların alınmasını sağlayabilirsin.

$tip = $_FILES['dosya']['type'];
$isim = $_FILES['dosya']['name'];
$uzanti = explode('.', $uzanti);
$uzanti = $uzanti[count($uzanti)-1];
if($tip != 'image/jpeg' || $uzanti != 'jpg') {
   echo 'Yanlızca JPG dosyaları gönderebilirsiniz.';
} else {
// ...

Son olarak da dosya tüm koşulları geçtiğinde onu copy() fonksiyonu ile geçici dizinden 2. parametresine yazdığımız dosyalar klasörüne göndermiş olduk.

$dosya = $_FILES['dosya']['tmp_name'];
copy($dosya, 'dosyalar/' . $_FILES['dosya']['name']);
echo 'Dosyanız upload edildi!';

Bir başka PHP serüvenlerinde görüşmek üzere esen kalın!

Etiketler:

Yazılanlar ilgini çektiyse, yenilerinden haberdar olmak için e-mail bültenine abone olabilirsin.

"PHP ile dosya upload" yazısı için 52 yorum yapılmış.

  1. […] PHP ile dosya upload. […]

  2. Halil dedi ki:

    peki bu dosyalar bizim kendi sunucumuzda mı barınıyor?

  3. engin dedi ki:

    $uzanti = explode(‘.’, $uzanti); satırı
    $uzanti = explode(‘.’, $isim); olmalı

  4. Samet dedi ki:

    Teşekkürler

  5. cihankoc.org dedi ki:

    merhaba benim bi sorum olacaktı örneğin bir resim upload ederken bu resmmin boyutunu küçülterek kayıt etmemiz mümkünmüdür

  6. Astald dedi ki:

    dosya uzantısını bu şekilde yapsanız daha sağlıklı olur
    $uzanti = @end(explode(‘.’, $isim));

  7. HAliÇ dedi ki:

    Muhteşem olmuş elinize sağlık..
    Bana öyle çok karmaşık geliyodu ki dosya yükleme basitleştirmişsiniz..

  8. eyaz dedi ki:

    bu dosyalar nerdeye yuklenıyor

  9. Yavuz Macit dedi ki:

    if(isset($_FILES['dosya'])) {
    echo 'Dosya gönderilmiş';
    } else {
    echo 'Lütfen bir dosya gönderin';
    }

    kontrolü dosya seçilsede seçilmesede, göndere bastığımız da dosya gönderildi sonucunu veriyor. Neden çalışmıyor?

    • Musa Avcı dedi ki:

      $_FILES['dosya'] değişkeni dosya seçilse de seçilmese de gönderilir, dosyanın varlığını kontrol etmek için $_FILES['dosya']['size'] == 0 koşulu ile dosya boyutuna ya da $_FILES['dosya']['error'] == 0 hata koduna bakarak karar verin.

  10. veysel dedi ki:

    Anlatım gayet sade ve anlaşılır. Teşekkürler.

  11. Yüksel Acı dedi ki:

    Bu dosyayı yüklerken dosyanın ismini değiştirerek kaydetmek için nasıl bir kod eklememiz gerekir, yardım ederseniz çok sevinirim.

    • Musa Avcı dedi ki:
      copy($dosya, 'dosyalar/' . $_FILES['dosya']['name']);

      yukarıdaki satırda 2. parametrede olmasını istediğiniz dosya adı ve dizinini ifade edebilirsiniz;

      copy($dosya, 'dosyalar/yuklenen_dosya_adi.jpg');
  12. Yüksel Acı dedi ki:

    ben dosyanın ismini değiştiren bir çare buldum yardımların için teşekkürler, yalnız kafayı sıyırma noktasına getiren bir hata yapıyorum sanırım yardımcı olursan sevinirim. şöyle ki image/jpeg ve jpg uzantısı için tek başına kontrol kodunu yazdığımda gayet güzel çalışıyor kod, jpg dışında format almıyor, ben iki format daha ekleyince jpg dahil hiçbirşey kabul etmiyor, nerede yanlış yapıyorum bir el atar mısın, şimdiden teşekkür ederim, kodum aşağıdaki gibi,

    if(($tip != ‘image/jpeg’) || ($tip != ‘image/png’) || $tip != ‘image/gif’ || $uzanti == ‘jpg’ || $uzanti == ‘gif’ || $uzanti == ‘png’)

  13. Yüksel Acı dedi ki:

    fazladan parantez gelmiş o şekilde de denemiştim hepsini parantez içine ayrı ayrı alarak, son ve çalışmayan hali şu şekilde.

    if($tip != ‘image/jpeg’ || $tip != ‘image/png’ || $tip != ‘image/gif’ || $uzanti == ‘jpg’ || $uzanti == ‘gif’ || $uzanti == ‘png’)

  14. Fatih dedi ki:

    Peki ben bu scriptle html dosyası upload etmek istiyorum nasıl değştirmem gerekiyo çünkü şöyle yapıyorum olmuyor yüklenemez mesajı dönüyor ;
    if($tip != ‘html’ || $uzanti != ‘html’) {
    echo ‘Yanlızca html dosyaları gönderebilirsiniz.’;
    } else {….

  15. Gökhan dedi ki:

    Ellerinize emeğinize sağlık. Bu kodda dosya uzantısı değiştiriğim zaman çalışmıyor. bunu nasıl yapaibliriz?

    • Musa Avcı dedi ki:

      yaşadığınız sorunu tam olarak anlamadım, biraz daha detaylı anlatıp kodlarınızı da paylaşabilirseniz daha iyi yardımcı olabilirim.

  16. hasan dedi ki:

    ben bir iletişim formuna ziyaretçilere resim upload ettirmek istiyodum.onu yaptım.
    hedef klasöre resimler yükleniyor.ve mailimede iletişim formumda ki bilgiler geliyo.ama ben hedefteki resim dosyaları maile ekte olarak ekletmek istiyorum nasıl yapabiliz.hazır şeyler var ama bilmediğm şeyleri kullanmak istemedim. yardımcı olabilirsen memnun olurum .

  17. musti dedi ki:

    Tüm bunları birleştirip bir paket şeklinde indirime hazır ekleyebilirseniz çok makbule geçecek. Özellikle bizim gibi başlangıçtaki arkadaşlar için… Teşekkürler

  18. burhan dedi ki:

    $uzanti = explode(‘.’, $isim);
    $uzanti = $uzanti[count($uzanti)-1];

    buradaki olayı tam olarak anlamadım.ufak bir detay verebilirmisiniz.

  19. Fahri ÇAKAR dedi ki:

    “$uzanti = explode(‘.’, $isim);
    $uzanti = $uzanti[count($uzanti)-1];
    buradaki olayı tam olarak anlamadım.ufak bir detay verebilirmisiniz.”

    $isim dosyanın ismi ve uzantısını birlikte içeren değişkendir.
    yani “Araba01.jpg”
    Burdaki isimde dosya uzantısını bulmak kolaydır, noktadan sonraki kısımdır.
    Ama bazen içinde daha fazla nokta bulunan isimler de gelebilir. En son noktadan sonraki kısım uzantıdır.
    $isim değişkeninin içeriğini bu noktalardan ayırarak bir dizi değer elde ediyoruz.
    Bu dizinin son elemanı dosyanın uzantısını ifade gösterir bu durumda.
    Dizinin son elemanının numarası da, elemanSayisi-1 dir.

  20. okan dedi ki:

    1 den fazla upload yaparken bu kodları nasıl kullanacağız?

  21. Eser dedi ki:

    Farklı dosya yükleme ve dosya isimlerinin çakışmalarını önlemek için kendime göre düzenleme yaptım. Umarım işinizi görür.

    if(isset($_FILES[‘dosya’])){
    $hata = $_FILES[‘dosya’][‘error’];
    if($hata != 0) {
    echo ‘Yüklenirken bir hata gerçekleşmiş.’;
    } else {
    $boyut = $_FILES[‘dosya’][‘size’];
    if($boyut > (1024*1024*3)){
    echo ‘Dosya 3MB den büyük olamaz.’;
    } else {
    $tip = $_FILES[‘dosya’][‘type’];
    $isim = $_FILES[‘dosya’][‘name’];
    $uzanti = explode(‘.’, $isim);
    $uzanti = $uzanti[count($uzanti)-1];
    $yeniad = substr(md5(uniqid(rand())), 0,10);
    $yenidosya = “”.$yeniad.”.”.$uzanti.””;
    if($uzanti!=’pdf’ && $uzanti!=’doc’ && $uzanti!=’docx’) {
    echo ‘Yanlızca PDF ve DOC dosyaları gönderebilirsiniz.’;
    } else {
    $dosya = $_FILES[‘dosya’][‘tmp_name’];
    copy($dosya, ‘dosyalar/’ . $yenidosya);
    echo ‘Dosyanız upload edildi!’;
    }
    }
    }
    }

    • Ünal dedi ki:

      if($uzanti!=’pdf’ && $uzanti!=’doc’ && $uzanti!=’docx’) aradaki operatörler && yerine || olmayacak mı???

  22. Merhaba, Öncelikle ellerinize sağlık, ben hiç kod bilgisine sahip olmadığım halde yazılarınızdan kendime göre bir şeyler hazırlayabiliyorum. Ancak, yukarıdaki upload dizinini kullandığımda “a 404 Not Found…” yanıtı alıyorum. Sitemde dosyalar klasörünü de açtım (public_html içinde), başka bir klasör daha açmam gerekiyor mu? Cevabınızı, kod yazma bilgisine sahip olmayan birine yazarsanız sevinirim. Saygılarımla…

  23. Doğan dedi ki:

    Peki içerik oluşturma sayfasında bunu nasıl uygulayacagız ve yüklenen resmin sadece o konuda çıkmasını sağlayabiliriz?
    Birden çok input alanı olduğu için kafam çok karıştı lütfen yardımlarınızı eksik etmeyin 🙂

  24. Ali dedi ki:

    dosyalar/

    klasörü bilgisayarın neresinde?

  25. cem dedi ki:

    bu dosya nerededir.Dosya Seç ve dosya seçilmedi adını değiştirmek istiyorum fakat nereden değişecek bulamadım

  26. ibrahim dedi ki:

    doc dosyaları yüklemek için ne yapmalıyım

  27. Taha dedi ki:

    Merhabalar, yüklenilen dosyaları otomatik olarak isimlendirmek için nasıl bir döngü kullanabiliriz.
    dosya1.pdf
    dosya2.pdf olarak otomatik adlandırsa, veya tarihsel olarak
    29122014-1717.pdf
    30122014-1259.pdf gibi.

  28. Hocam çok teşekkür ederim.Sürekli takip ediyorum burayı ve çok faydasını gördüm.Başarılarının devamını diliyorum.

  29. devrim dedi ki:

    mrb. hocam. benim yapamayacağım yapmayı çok istediğim birşey var lütfen yardımcı olurmusunuz. binlerce sitede rersim slayt kodu verilmiş. resimler yolları php dosyası içinde atıyorum img src = ‘upload/1.jpg’ ikinci resim ise 2.jpg şeklinde resimleri slayt yaptırmışlar. ama ben yönetim panelinden resimleri istediğim zaman değiştirmek istiyorum. resimleri upload klasörüne upload ediyorum ama resim adı değişik oluyor. resimleri upload ederken sırasıyla 1.jpg 2.jpg adında kaydedemeyizmi. yada upload edilen resmin yeni adını php dosyasındakinin yerine yazdırarak değiştiremeyizmi bi çare bulmam lazım. tşk.

  30. hakan dedi ki:

    beyler atıyorum 15 tane resim dosyasını upload ederken bayaa bekliyorum(bir dosya 3 mb olsa 45 mb upload edilene kadar bekliyor) bunu nasıl aşabilirim yardımcı olabilecek kimse var mı ? Dosyaların boyutunu küçülterek almak gibi mesela

  31. ahmet selim dedi ki:

    merhaba,ben ilan sitesi için yönetim panelimde bir form oluşturdum.formdan ilan başlığı,adresi,açıklamsı giriliyor ve bir de resim seçiliyor.resimleri kopyalıyor ve adresini mysql e kayıt ediyor.Peki nasıl bir den fazla resim ekleyip uzantıları veritabanına kayıt edebilirim??

  32. ismail dedi ki:

    Hocam Ben sizin yaptığınız gibi yaptım oldu fakat daha büyük boyutlu dosyaları yüklemiyor örn:(Uzun Videolar) yardımcı olursanız çok sevinirim

    • Musa Avcı dedi ki:

      php.ini dosyasından aşağıdaki değerleri yükseltmen gerekiyor;


      ; Maximum allowed size for uploaded files.
      upload_max_filesize = 40M

      ; Must be greater than or equal to upload_max_filesize
      post_max_size = 40M

  33. dora dedi ki:

    Hocam yaptığınız gibi yaptım küçük dosyalarda işe yarıyor fakat 1.5 GB boyutunda bir dosya yükleyemiyorum bunun cozumunu söylerseniz sevinirim

  34. fatih dedi ki:

    Merhaba bu php kodlarının dosyalanmış olarak indirmemiz mümkünmü yardımlarınız için şimdiden teşekkür ederiz.

  35. orxan dedi ki:

    salam.bir sualim olacaqdir dosyanin nereye duwmesin nasil duzenleye biliriz?

  36. mustafa dedi ki:

    Linux işletim sistemi kullanıyorum apache server üzerinde php ile hiçbir hata almıyorum ama dosya veya dizin oluşturamıyorum. Aynı şekilde Upload uygulamasını yaptım hiçbir hata almıyorum “Dosyanız upload edildi” mesajını da alıyorum ama dosya upload edilmiyor.

  37. yunus ç dedi ki:

    if($tip ile başlayan sorgu
    if{$uzanti} olmalı

  38. bünyamin dedi ki:

    dosya url sını veritabanına nasıl ekletebılırım aynı anda peki?

  39. İsmail dedi ki:

    $uzanti = explode(‘.’, $isim);
    $uzanti = $uzanti[count($uzanti)-1]; bunun yerine aşağıdakini kullansanız daha pratik olmaz mıydı?
    $uzanti = substr($isim,-3);

  40. mustafa dedi ki:

    super bir anlatım cok teşekkürler..

  41. Abdulsamed demek istememişti ama yinede dedi ki:

    Çok teşekkürler işime yaradı :))

  42. Blogger Temaları dedi ki:

    Hocam teşekkürler aradığım dersleri blogunuzda buldum 🙂

Bir Cevap Yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir