Dosyaları PHP'ye yüklerken $ _FILES neden boş olsun?


148

Windows 7 bilgisayarıma WampServer 2 kurdum. Apache 2.2.11 ve PHP 5.2.11 kullanıyorum. Bir formdan herhangi bir dosya yüklemeye çalıştığımda yükleme yapıyor gibi görünüyor, ancak PHP'de $_FILESdizi boş. c:\wamp\tmpKlasörde dosya yok . php.iniDosya yüklemelerine vb. İzin verecek şekilde yapılandırdım . tmpKlasör geçerli kullanıcı için okuma / yazma ayrıcalıkları vardır. Şoktayım.

HTML:

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
    <form enctype="multipart/form-data" action="vanilla-upload.php" method="POST">
        Choose a file to upload: <input name="uploadedfile" type="file" /><br />
        <input type="submit" value="Upload File" />
    </form>
</body>
</html>

PHP:

<?php
echo 'file count=', count($_FILES),"\n";
var_dump($_FILES);
echo "\n";
?>

2
Hata günlüklerini kontrol ettiniz mi?
Byron Whitlock

Eminim gözden kaçırdığın aptalca bir şey vardır. Örneğin, kodun içinde olduğundan emin misiniz vanilla-upload.php?
Luca Matteis

Ha ben de aynı sorunu yaşıyordum. Hata günlüklerini kontrol ettim ve izin verilen maksimum boyutu aşan bir dosyanın yüklendiğini söyledi.
BrightIntelDusk

Yanıtlar:


511

PHP'de dosya yüklemek için bir kontrol listesi:

  1. Php.ini'yi kontrol edin:
    file_uploads = On
    post_max_size = 100M
    upload_max_filesize = 100M

    • Kullanmanız gerekebilir .htaccessveya .user.inipaylaşılan barındırma üzerindeyseniz ve erişiminiz yoksa php.ini.
    • Doğru ini dosyasını düzenlediğinizden emin olun - phpinfo()ayarlarınızın gerçekten uygulandığını doğrulamak için işlevi kullanın.
    • Ayrıca emin boyutları misspell değil yetinmek - olması gerektiği 100M değil 100MB .
  2. <form>Etiketinizin enctype="multipart/form-data"özniteliğe sahip olduğundan emin olun . Başka hiçbir etiket çalışmaz, sizin FORM etiketiniz olmalıdır. Doğru yazıldığını iki kez kontrol edin . Çok parçalı / form verilerinin, Word'den VEYA bir web sitesi blogundan yapıştırılan akıllı tırnakların değil, DÜZ QUOTES ile çevrili olduğunu iki kez kontrol edin (WordPress, düz tırnakları açılı tırnaklara dönüştürür!). Sayfada birden çok formunuz varsa, her ikisinin de bu özelliğe sahip olduğundan emin olun. Bunları elle yazın veya elle yazılan düz tek tırnakları deneyin.

  3. Aynı nameözniteliğe sahip iki girdi dosyası alanınız olmadığından emin olun . Birden fazla destek vermeniz gerekiyorsa, adın sonuna köşeli parantez koyun:

    <input type="file" name="files[]">
    <input type="file" name="files[]">
    
  4. Tmp ve karşıya yükleme dizinlerinizin doğru okuma + yazma izinlerine sahip olduğundan emin olun. Geçici yükleme klasörü PHP ayarlarında olarak belirtilir upload_tmp_dir.

  5. Dosya hedefinizin ve tmp / upload dizinlerinizin içlerinde boşluk olmadığından emin olun.

  6. <form>Sayfanızdaki tüm öğelerin </form>yakın etiketlere sahip olduğundan emin olun .

  7. FORM etiketinizin bulunduğundan emin olun method="POST". GET istekleri, çok parçalı / form veri yüklemelerini desteklemez.

  8. Dosya giriş etiketinizin bir NAME özniteliğine sahip olduğundan emin olun. Bir kimlik özelliği yeterli DEĞİLDİR! Kimlik özellikleri POST yükleri için değil, DOM'da kullanım içindir.

  9. <input type="file">Gönderim sırasında alanınızı devre dışı bırakmak için Javascript kullanmadığınızdan emin olun

  10. Gibi formları iç içe geçirmediğinizden emin olun. <form><form></form></form>

  11. HTML yapınızı geçersiz / çakışan etiketler için kontrol edin. <div><form></div></form>

  12. Ayrıca, yüklediğiniz dosyanın içinde alfasayısal olmayan karakterler bulunmadığından emin olun.

  13. Bir keresinde bunun neden birdenbire başıma geldiğini anlamaya çalışmak için saatler harcadım. İçinde bazı PHP ayarlarını değiştirdiğim .htaccessve bunlardan birinin (hangisi henüz emin değilim) yüklemenin başarısız olmasına ve $_FILESboş olmasına neden olduğu ortaya çıktı .

  14. Potansiyel olarak etiketin özniteliğinde alt çizgilerden ( _) kaçınmayı deneyebilirsinizname=""<input>

  15. Dosya boyutu sorunu olup olmadığını daraltmak için çok küçük dosyalar yüklemeyi deneyin.

  16. Kullanılabilir disk alanınızı kontrol edin. Çok nadir de olsa, bu PHP Kılavuzu sayfası yorumunda bahsedilmektedir :

    $ _FILES dizisi aniden gizemli bir şekilde boşalırsa, formunuz doğru görünse bile, geçici klasör bölümünüz için kullanılabilir disk alanını kontrol etmelisiniz. Kurulumumda tüm dosya yüklemeleri uyarı vermeden başarısız oldu. Çok fazla diş gıcırdattıktan sonra, ek alan boşaltmaya çalıştım, ardından dosya yüklemeleri birdenbire tekrar çalıştı.

  17. Formu, sayfanın yeniden yüklenmesine neden olan normal bir POST isteği yerine bir AJAX POST isteği aracılığıyla göndermediğinizden emin olun. Yukarıdaki listedeki her noktayı gözden geçirdim ve sonunda $ _FILES değişkenimin boş olmasının nedeninin AJAX POST isteği kullanarak formu göndermem olduğunu öğrendim. Ajax kullanarak dosya yüklemek için yöntemler olduğunu biliyorum, ancak bu, $ _FILES dizinizin boş olmasının geçerli bir nedeni olabilir.

Bu noktaların bazılarının kaynağı:
http://getluky.net/2004/10/04/apachephp-_files-array-mysteriously-empty/


16
Belki "kabul edildi" cevabı orijinal gönderiyi çözdü, ancak bu cevap en yararlı bulduğum cevap. Şüphe duyduğunuzda, tarayıcının göründüğü gibi kaynağa bakın. Bu listedeki her bir öğeyi kontrol edip geriye doğru giderken, hatamı hiç beklenmedik bir yerde buldum. Benzer bir sorunla mücadele ediyorsanız, inanın bana, muhtemelen Apache'de bir hata değil. ;)
quickthyme

3
Ayrıca, dosya girişini içeren form öğenizin başka bir form öğesinin alt öğesi OLMADIĞINDAN emin olun. örneğin<form><form><input type="file"></form></form>
sudee

3
Vaov! bu liste için teşekkür ederim. benim sorunum 2 numaraydı. $('#my-form')[0].reset();Gönder işleyicide arıyordum .
Gavin

2
Teşekkürler. benim durumumda 7. enctype = "multipart / form-data" suçluydu.
Thupten

3
DUDE, sen bir cankurtaransın. Bunu anlamaya çalışmak için saatler harcıyorum (2) benim sorunumdu ... Teşekkürler!
Mike Q

74

HTML'ye gelince, bu bölümü doğru bir şekilde ayarlamış görünüyorsunuz. Zaten sahipsinenctype="multipart/form-data"Formda olması çok önemli .

php.iniKurulumunuza gelince , bazen sistemlerde birden fazla php.inidosya bulunur. Doğru olanı düzenlediğinizden emin olun. php.iniDosyanızı dosya yüklemeleri için yapılandırdığınızı söylediğinizi biliyorum , ancak aynı zamanda upload_max_filesizeve post_max_sizeyüklemeye çalıştığınız dosyadan daha büyük olacak şekilde ayarladınız mı? Yani sahip olmalısın:

file_uploads = On; sounds like you already did this
post_max_size = 8M; change this higher if needed
upload_max_filesize = 8M; change this higher if needed

Dizininiz: "c:\wamp\tmp"hem okuma hem de yazma izinlerine sahip mi? php.iniDeğişiklikleri yaptıktan sonra Apache'yi yeniden başlatmayı unuttunuz mu?



4
+1: Apache sunucusunu yeniden başlatmak için ipucu. Birçok Windows kullanıcısı bunu unutur.
shamittomar

36

enctype="multipart/form-data"Formunuza eklemek önemlidir , örnek

<form action="upload.php" method="post" enctype="multipart/form-data">
    Select image to upload:
    <input type="file" name="fileToUpload" id="fileToUpload">
    <input type="submit" value="Upload Image" name="submit">
</form>

14

Çeşitli kapsamlı cevaplar için herkese teşekkür ederim. Bunların hepsi çok faydalıdır. Cevabın çok tuhaf olduğu ortaya çıktı. PHP 5.2.11'in aşağıdakilerden hoşlanmadığı ortaya çıktı:

post_max_size = 2G

veya

post_max_size = 2048M

Olarak değiştirirsem 2047M, yükleme çalışır.


18
Bu kadar yüksek bir değerin, alan dışı / ddos ​​saldırılarına karşı bir güvenlik açığı olduğunu unutmayın. Bunu ekledikten sonra insanlar çözümünüzü kopyalayıp yapıştırmaya çalıştıklarında bunun çok fazla olduğunu fark etsinler. Her neyse, 2 konser çok uzun bir yükleme süresi gerektirir.
Manuel Arwed Schmidt

Artık çok büyük değil. 1-3G aralığında dosyaları oldukça düzenli olarak yükleyen müşterilerimiz var. Dosyaları kendi sunucularına yüklediklerinden ve IP beyaz listeye alınmış sunucular olduklarından, değişim oldukça normaldir ve sadece bir müşterinin ekipmanını kullanmak istediği şekilde kullanmasına izin vermenin bir yoludur. Faturaları ödüyorlar, güvenlik riski yok, sorun yok.
TheSatinKnight

8

2 saate bakmakla aynı bir problemim var, önce sunucu yapılandırmamızı kontrol etmemiz çok basit.

Misal:

echo $upload_max_size = ini_get('upload_max_filesize');  
echo $post_max_size=ini_get('post_max_size');   

herhangi bir dosya boyutu türü :20mb, ancak bizim upload_max_sizeyukarıda 20mbama dizi null. Cevap şundan post_max_sizebüyük olmalı upload_max_filesize

post_max_size = 750M  
upload_max_filesize = 750M

6

Burada bulduğum başka bir neden: JQuery Mobile kullanırken ve data-ajax form özniteliği true olarak ayarlandığında, FILES dizisi boş olacaktır. Yani data-ajax'ı false olarak ayarlayın.


5

Giriş öğenizin bir "ad" özelliğine sahip olduğundan emin olun. <input type="file" name="uploadedfile" />

Eksikse $ _FILES boş olacaktır.


5

Aynı problemle mücadele ediyor ve her şeyi test ediyordum, hata bildirimi almıyordum ve hiçbir şey yanlış görünmüyordu. Error_reporting (E_ALL) yaşadım Ama aniden apache günlüğünü kontrol etmediğimi fark ettim ve işte! Komut dosyasında bir sözdizimi hatası oluştu ...! (özlemek "}" )

Öyleyse, bu kontrol edilmesi gereken bir şey olsa bile unutulabilir ... Benim durumumda (linux) şu adrestedir:

/var/log/apache2/error.log

3

Kimse bundan bahsetmedi ama bana yardımcı oldu ve internetteki pek çok yerde bundan bahsetmedi.

Php.ini'nizin aşağıdaki anahtarı ayarladığından emin olun:

    upload_tmp_dir="/path/to/some/tmp/folder"

Mutlak bir sunucu dosyası yolu kullanmanızı isteyip istemediklerini web barındırıcınızla kontrol etmeniz gerekir. Bunu belirlemek için php.ini dosyanızdaki diğer dizin örneklerini görebilmelisiniz. Ayarladığım anda _FILES nesnemde değerler alıyorum.

Son olarak, tmp klasörünüzün ve dosyaları taşıdığınız her yerde okunup yazılabilmeleri için doğru izinlere sahip olduğundan emin olun.


2

Bir dizi dosya yüklemeye çalışıyorsanız max_file_uploads, php.inibu durumda varsayılan olarak şu şekilde ayarlanmış olanı artırmanız gerekebilir :20

Not : max_file_uploadsphp.ini dışında DEĞİŞTİRİLEMEZ. Bkz PHP "Bug" # 50684


2

Bir başka olası suçlu apache yönlendirmeleridir. Benim durumumda, apache'nin httpd.conf'u, sitemizdeki belirli sayfaları http sürümlerine ve diğer sayfaları, daha önce yapılmamışlarsa, sayfanın https sürümlerine yeniden yönlendirecek şekilde ayarlamıştım. Dosya girişi olan bir formun olduğu sayfa, ssl'yi zorlamak için yapılandırılmış sayfalardan biriydi, ancak formun eylemi olarak belirlenen sayfa http olarak yapılandırılmıştı. Böylece sayfa, yüklemeyi eylem sayfasının ssl sürümüne gönderirdi, ancak apache bunu sayfanın http sürümüne yönlendiriyordu ve yüklenen dosya dahil olmak üzere gönderi verileri kayboldu.



2

sys_get_temp_dirPaylaşılan bir barındırma ortamındaysanız tarafından sağlanan geçici klasör konumuna güvenmeyin .

İşte henüz bahsedilmeyen bir şey daha var ...

Doğal olarak, PHP betiğimin geçici dosya yüklemelerini depoladığı klasörün olduğunu varsaydım /tmp. Bu inanç, echo sys_get_temp_dir() . PHP_EOL;geri dönmesi gerçeğiyle pekiştirildi /tmp. Ayrıca echo ini_get('upload_tmp_dir');hiçbir şey döndürmez.

Yüklenen dosyanın aslında /tmpklasörümde kısaca göründüğünü doğrulamak için, sleep(30);komut dosyama bir ifade ekledim ( burada önerildiği gibi ) ve dosyama gittim/tmp ve dosyayı bulmak için cPanel Dosya Yöneticisindeki klasörüme . Ancak, ne olursa olsun, yüklenen dosya orada hiçbir yerde bulunamadı.

Bunun nedenini belirlemek için saatler harcadım ve burada sunulan her öneriyi uyguladım.

Son olarak, web sitesi dosyalarımda sorgu için arama yaptıktan sonra tmp, sitemin tmpfarklı dizinlerde adlandırılmış başka klasörler içerdiğini keşfettim . PHP betiğimin aslında yüklenen dosyaları yazdığını.cagefs/tmp fark ettim . ( "Gizli Dosyaları Göster" Bu klasörü görüntülemek için cPanel'de ayarı etkinleştirilmelidir.)

Öyleyse, sys_get_temp_dirişlev neden yanlış bilgi döndürüyor?

İşte PHP.net web sayfasından şu konuya ilişkin bir açıklama sys_get_temp_dir(yani, en iyi yorum):

Systemd'nin PrivateTmp = true olduğu bir Linux sisteminde (CentOS 7 ve belki de diğer yeni dağıtımlarda varsayılandır) çalıştırılıyorsa, bu işlev yalnızca "/ tmp" döndürür, doğru değil, çok daha uzun, biraz dinamik yol.

Bu SO gönderisi konuyu da araştırıyor:


1

Ana komut dosyanız, http://Some_long_URL/index.phpalanda tam URL'yi (açık olarak index.phpve yalnızca değilhttp://Some_long_URL ) belirtmeye dikkat ediyorsanız action. Şaşırtıcı bir şekilde, değilse, doğru komut dosyası çalıştırılır, ancak en boş $ _FILES!


1

Aynı sorunla karşılaştım ve sorunun IDE'm olduğunu öğrendim. Doğrudan tarayıcıyı kullanmak yerine hata ayıklayıcıyı doğrudan IDE'den (PHPStorm) başlatıyordum. IDE'nin ortaya çıkardığı URL şöyleydi:

"...localhost:63342/CB_Upload/index.php?_ijt=j2hcbacqepj87bvg66ncuohvne"

ve sadece şunu kullanarak:

"...localhost/CB_Upload/index.php"

gayet iyi çalıştı. Kurulumum PC / Windows 10 / WAMPSERVER 3.0.6 64bit


Burada da aynı şey, şimdiye kadar bir saat boyunca daireler çiziyordum! teşekkürler
EKanadily

0

Aynı sorunu yaşadım ve temaların hiçbiri benim hatam değildi. Varsa, .htaccess dosyanızı kontrol edin, "MultiViews" etkinse. Onları devre dışı bırakmak zorunda kaldım.


0

Benzer bir sorun yaşadım ve shamittomar'ın da bahsettiği gibi sorun htaccess'te yanlış değerdeydi.

Değişim php_value post_max_size 10MBiçinphp_value post_max_size 10M


0

Boştum $_FILESçünkü <form enctype="multipart/form-data" method="post">yerleştirdikten sonra

</div>
<div style="clear:both"></div>

İlk kod gibiydi

<span class="span_left">Photos (gif/jpg/jpeg/png) </span>
<form enctype="multipart/form-data" method="post">
<input name="files[]" type="file" id="upload_file" />
<input type="button" id="upload" value="Upload photo" />
</form>

Değiştirmeye karar verdim ve

<div>
<span class="span_left">Photos (gif/jpg/jpeg/png) </span>
<form enctype="multipart/form-data" method="post">
</div>
<div style="clear:both"></div>
<input name="files[]" type="file" id="upload_file" />
<input type="button" id="upload" value="Upload photo" />
</form>
<div style="clear:both"></div>

Sonuç şu ki, sonra <form enctype="multipart/form-data" method="post">olmalı <input name, type, idve olmamalı<div> veya başka etiketler

Benim durumumda doğru kod

<div>
<span class="span_left">Photos (gif/jpg/jpeg/png) </span>
</div>
<div style="clear:both"></div>
<form enctype="multipart/form-data" method="post">
<input name="files[]" type="file" id="upload_file" />
<input type="button" id="upload" value="Upload photo" />
</form>
<div style="clear:both"></div>

0

Ben de $ _FILES boşluğu ile ilgili sorunlar yaşadım. Yukarıdaki kontrol listesi .htaccess, httpd.conf veya httpd-vhost.conf içindeki MultiViews'tan bahsetmez.

Web sitesini içeren dizininiz için seçenekler direktifinde MultiViews ayarlanmışsa, yüklediğim dosyanın İçeriği-Uzunluk başlığı gösteriliyorsa $ _FILES boş olacaktır.


0

JQuery Mobile kullanıyorsanız

Bir dosya girişiyle çok parçalı form kullanmak Ajax tarafından desteklenmez. Bu durumda, formun sunucuya doğru bir şekilde gönderildiğinden emin olmak için ana formu data-ajax = "false" ile dekore etmelisiniz.

<form action="upload.php" method="post" enctype="multipart/form-data"  data-ajax="false">
    Select image to upload:
    <input type="file" name="fileToUpload" id="fileToUpload">
    <input type="submit" value="Upload Image" name="submit">
</form>

0

Kullanmakta olduğunuz sayfadan formunuzu, yalnızca form ve php kodu içeren basit bir php sayfasına ayırın ve bu şekilde test edin.

Herhangi bir önyükleme veya java betiği _FILES [] 'i temizleyebilir. Bu benim davamdı

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.