Mengapa $ _FILES kosong saat mengunggah file ke PHP?

145

Saya telah menginstal WampServer 2 di komputer Windows 7 saya. Saya menggunakan Apache 2.2.11 dan PHP 5.2.11. Ketika saya mencoba untuk mengunggah file apa pun dari formulir, sepertinya akan mengunggah, tetapi dalam PHP, $_FILESarraynya kosong. Tidak ada file dic:\wamp\tmp folder. Saya telah mengkonfigurasi php.iniuntuk mengizinkan unggahan file dan semacamnya. The tmpfolder telah membaca hak / tulis untuk pengguna saat ini. Saya bingung.

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";
?>
elmonty
sumber
2
Sudahkah Anda memeriksa log kesalahan?
Byron Whitlock
Saya yakin ada sesuatu yang Anda abaikan. Misalnya, Anda yakin memasukkan kode vanilla-upload.php?
Luca Matteis
Ha saya mengalami masalah yang sama. Saya memeriksa log kesalahan dan mengatakan bahwa file sedang diunggah yang melebihi ukuran maksimum yang diizinkan.
BrightIntelDusk

Jawaban:

493

Berikut daftar periksa untuk mengunggah file dalam PHP:

  1. Periksa php.ini untuk:
    file_uploads = On
    post_max_size = 100M
    upload_max_filesize = 100M

    • Anda mungkin perlu menggunakan .htaccessatau .user.inijika Anda menggunakan hosting bersama dan tidak memiliki akses ke php.ini.
    • Pastikan Anda mengedit file ini dengan benar - gunakan phpinfo()fungsi ini untuk memverifikasi bahwa pengaturan Anda benar-benar diterapkan.
    • Pastikan juga Anda tidak salah mengeja ukurannya - seharusnya 100M tidak 100MB .
  2. Pastikan <form>tag Anda memiliki enctype="multipart/form-data"atribut. Tidak ada tag lain yang berfungsi, itu harus menjadi tag FORMULIR Anda. Periksa kembali apakah itu dieja dengan benar . Periksa ulang apakah multipart / formulir-data dikelilingi oleh KUTIPAN LURUS, bukan kutipan cerdas yang disisipkan dari Word ATAU dari blog situs web (WordPress mengonversi kutipan langsung menjadi kutipan sudut!). Jika Anda memiliki beberapa formulir di halaman, pastikan keduanya memiliki atribut ini. Ketikkan secara manual, atau coba langsung satu kutip yang diketikkan secara manual.

  3. Pastikan Anda tidak memiliki dua bidang file input dengan nameatribut yang sama . Jika Anda perlu mendukung banyak, letakkan tanda kurung di akhir nama:

    <input type="file" name="files[]">
    <input type="file" name="files[]">
  4. Pastikan direktori tmp dan unggah Anda memiliki izin baca + tulis yang benar. Folder unggahan sementara ditentukan dalam pengaturan PHP sebagai upload_tmp_dir.

  5. Pastikan tujuan file Anda dan direktori tmp / unggah tidak memiliki spasi di dalamnya.

  6. Pastikan semua yang ada <form>di halaman Anda memiliki </form>tag penutup.

  7. Pastikan tag FORMULIR Anda sudah method="POST". Permintaan GET tidak mendukung unggahan multipart / formulir-data.

  8. Pastikan tag input file Anda memiliki atribut NAME. Atribut ID TIDAK memadai! Atribut ID untuk digunakan dalam DOM, bukan untuk muatan POST.

  9. Pastikan Anda tidak menggunakan Javascript untuk menonaktifkan <input type="file">bidang Anda saat pengiriman

  10. Pastikan Anda tidak suka bentuk sarang <form><form></form></form>

  11. Periksa struktur HTML Anda untuk tag yang tidak valid / tumpang tindih <div><form></div></form>

  12. Pastikan juga file yang Anda unggah tidak memiliki karakter non-alfanumerik di dalamnya.

  13. Suatu kali, saya hanya menghabiskan waktu berjam-jam untuk mencari tahu mengapa ini terjadi pada saya secara tiba-tiba. Ternyata saya telah memodifikasi beberapa pengaturan PHP .htaccess, dan salah satunya (belum yakin mana) yang menyebabkan unggahan gagal dan $_FILESkosong.

  14. Anda berpotensi mencoba menghindari garis bawah ( _) pada name=""atribut <input>tag

  15. Coba unggah file yang sangat kecil untuk mempersempit apakah itu masalah ukuran file.

  16. Periksa ruang disk Anda yang tersedia. Meskipun sangat jarang, disebutkan dalam komentar halaman Manual PHP ini :

    Jika array $ _FILES tiba-tiba kosong secara misterius, meskipun formulir Anda tampaknya benar, Anda harus memeriksa ruang disk yang tersedia untuk partisi folder sementara Anda. Dalam instalasi saya, semua unggahan file gagal tanpa peringatan. Setelah banyak kertakan gigi, saya mencoba membebaskan ruang tambahan, setelah itu unggahan file tiba-tiba bekerja lagi.

  17. Pastikan Anda tidak mengirimkan formulir melalui permintaan POST AJAX alih-alih permintaan POST normal yang menyebabkan halaman dimuat ulang. Saya memeriksa setiap poin dalam daftar di atas, dan akhirnya menemukan bahwa alasan variabel $ _FILES saya kosong adalah karena saya mengirimkan formulir menggunakan permintaan POST AJAX. Saya tahu bahwa ada metode untuk mengunggah file menggunakan ajax juga, tetapi ini bisa menjadi alasan yang valid mengapa array $ _FILES Anda kosong.

Sumber untuk beberapa poin ini:
http://getluky.net/2004/10/04/apachephp-_files-array-mysteriously-empty/

shamittomar
sumber
12
Mungkin jawaban "diterima" telah menyelesaikan pos asli, tetapi jawaban ini adalah yang menurut saya paling bermanfaat. Jika ragu, lihat sumbernya seperti yang terlihat oleh browser. Memeriksa setiap item dalam daftar ini dan menelusuri ke belakang, saya menemukan kesalahan saya di tempat yang paling tak terduga. Jika Anda kesulitan dengan masalah yang sama, percayalah, itu mungkin bukan bug di Apache. ;)
quickthyme
3
Pastikan juga elemen form Anda yang berisi input file BUKAN anak dari elemen form lain. eg<form><form><input type="file"></form></form>
sudee
3
Wow! terima kasih untuk daftar ini. masalah saya adalah # 2. saya menelepon $('#my-form')[0].reset();di handler kirim.
Gavin
2
Terima kasih. dalam nomor kasus saya 7. enctype = "multipart / form-data" adalah penyebabnya.
Thupten
3
DUDE, Anda adalah penyelamat. Saya menghabiskan berjam-jam mencoba untuk mencari tahu ini (2) adalah masalah saya ... Terima kasih!
Mike Q
74

Sejauh HTML Anda tampaknya telah mengatur bagian itu dengan benar. Anda sudah memilikienctype="multipart/form-data" yang sangat penting untuk ada di formulir.

Sejauh php.inipengaturan Anda , kadang-kadang pada sistem ada beberapa php.inifile. Pastikan Anda mengedit yang benar. Saya tahu Anda mengatakan Anda telah mengonfigurasi php.inifile Anda untuk mengunggah file, tetapi apakah Anda juga mengatur upload_max_filesizedan post_max_sizemenjadi lebih besar dari file yang ingin Anda unggah? Jadi, Anda harus memiliki:

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

Apakah direktori Anda: "c:\wamp\tmp"memiliki izin baca dan tulis? Apakah Anda ingat untuk me-restart Apache setelah Anda melakukan php.iniperubahan?


Brian
sumber
4
+1: Untuk memulai kembali tip server Apache. Banyak pengguna Windows lupa akan hal itu.
shamittomar
36

Penting untuk menambahkan enctype="multipart/form-data"ke formulir Anda, misalnya

<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>
meda
sumber
14

Terima kasih semuanya atas jawaban komprehensif yang beragam. Itu semua sangat membantu. Jawabannya ternyata sangat aneh. Ternyata PHP 5.2.11 tidak menyukai yang berikut ini:

post_max_size = 2G

atau

post_max_size = 2048M

Jika saya mengubahnya 2047M, pengunggahan berfungsi.

elmonty
sumber
17
Perhatikan bahwa nilai tinggi seperti itu merupakan kerentanan terhadap serangan di luar ruang / ddos. Hanya menambahkan ini sehingga orang-orang terlalu sadar, ketika mereka mencoba menyalin & menempelkan solusi Anda. Bagaimanapun, 2 pertunjukan akan membutuhkan waktu unggah yang terlalu lama.
Manuel Arwed Schmidt
Tidak terlalu besar lagi. Kami memiliki klien yang mengunggah file dalam kisaran 1-3G dengan cukup teratur. Karena mereka mengunggah file ke server mereka sendiri, dan mereka adalah server yang masuk daftar putih IP, pertukaran itu cukup normal dan hanya cara untuk memungkinkan klien menggunakan peralatan mereka seperti yang mereka ingin menggunakannya. Mereka membayar tagihan, tidak melibatkan risiko keamanan, tidak ada masalah.
TheSatinKnight
8

Saya memiliki masalah yang sama dalam 2 jam, sangat mudah untuk memeriksa konfigurasi server kami terlebih dahulu.

Contoh:

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

semua jenis ukuran file :20mb, tetapi kami di upload_max_sizeatas 20mbtetapi array null. Jawabannya adalah kita post_max_sizeharus lebih besar dari upload_max_filesize

post_max_size = 750M  
upload_max_filesize = 750M
shashik493
sumber
6

Di sini penyebab lain yang saya temukan: Ketika menggunakan JQuery Mobile dan atribut data formulir-ajax disetel ke true, array FILES akan kosong. Jadi atur data-ajax ke false.

skakmat711
sumber
5

Pastikan elemen input Anda memiliki atribut 'nama'. <input type="file" name="uploadedfile" />

Jika ini tidak ada, $ _FILES akan kosong.

Adrian Parr
sumber
4

Saya berjuang dengan masalah yang sama dan menguji semuanya, tidak mendapatkan pelaporan kesalahan dan sepertinya tidak ada yang salah. Saya mengalami error_reporting (E_ALL) Tapi tiba-tiba saya menyadari bahwa saya belum memeriksa log apache dan voilà! Terjadi kesalahan sintaksis pada skrip ...! ("}" yang hilang

Jadi, meskipun ini adalah sesuatu yang jelas untuk diperiksa, itu bisa dilupakan ... Dalam kasus saya (linux) itu ada di:

/var/log/apache2/error.log
Luis Rosety
sumber
3

Tidak ada yang menyebutkan ini tetapi itu membantu saya dan tidak banyak tempat di internet yang menyebutkannya.

Pastikan php.ini Anda menetapkan kunci berikut:

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

Anda harus memeriksa dengan hosting Anda jika mereka ingin Anda menggunakan jalur file server absolut. Anda harus dapat melihat contoh direktori lain di file php.ini Anda untuk menentukan ini. Segera setelah saya atur, saya mendapat nilai di objek _FILES saya.

Akhirnya pastikan bahwa folder tmp Anda dan di mana pun Anda memindahkan file memiliki izin yang benar sehingga mereka dapat dibaca dan ditulis.

AaronP
sumber
2

Jika Anda mencoba untuk meng-upload sebuah array dari file maka Anda mungkin perlu untuk meningkatkan max_file_uploadsdi php.inimana adalah dengan set default20

Catatan : max_file_uploadsTIDAK BISA diubah di luar php.ini. Lihat PHP "Bug" # 50684

Tahir Yasin
sumber
2

Penyebab lain yang mungkin adalah pengalihan apache. Dalam kasus saya, saya memiliki httpd.conf apache yang diatur untuk mengalihkan halaman tertentu di situs kami ke versi http, dan halaman lain untuk https versi halaman, jika belum. Halaman di mana saya memiliki formulir dengan input file adalah salah satu halaman yang dikonfigurasikan untuk memaksa ssl, tetapi halaman yang ditunjuk sebagai aksi formulir dikonfigurasikan menjadi http. Jadi halaman tersebut akan mengirimkan unggahan ke versi ssl dari halaman tindakan, tetapi apache mengarahkannya ke versi http halaman dan data pos, termasuk file yang diunggah hilang.

pengguna2723315
sumber
2

Periksa php.ini Anda untuk enable_post_data_reading = Hidup , karena:

Menonaktifkan opsi ini menyebabkan $ _POST dan $ _FILES tidak terisi . Satu-satunya cara untuk membaca postdata akan melalui php: // input stream wrapper. (...)

Di http://php.net/manual/en/ini.core.php#ini.enable-post-data-reading

jmng
sumber
1

Jika skrip utama Anda http://Some_long_URL/index.phpberhati-hati untuk menentukan URL lengkap (dengan eksplisit index.phpdan tidak hanya http://Some_long_URL) di actionbidang. Anehnya, jika tidak, skrip yang tepat dieksekusi, tetapi dengan id kosong $ _FILES!

Gibbie
sumber
1

Saya mengalami masalah yang sama dan menemukan bahwa itu IDE saya adalah bagian dari masalah. Saya meluncurkan debugger langsung dari IDE (PHPStorm) alih-alih hanya menggunakan browser secara langsung. URL yang dihasilkan IDE adalah seperti ini:

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

dan hanya menggunakan:

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

bekerja dengan baik. Pengaturan saya adalah PC / Windows 10 / WAMPSERVER 3.0.6 64bit

Marc M.
sumber
hal yang sama di sini, saya berlari berputar selama satu jam sejauh ini! terima kasih
EKanadily
1

Jangan percaya lokasi folder temp yang disediakan oleh sys_get_temp_dirjika Anda berada di lingkungan hosting bersama.

Berikut ini satu hal lagi untuk diperiksa yang belum disebutkan ...

Saya berasumsi, secara alami, bahwa folder tempat skrip PHP saya menyimpan unggahan file sementara /tmp. Keyakinan ini diperkuat oleh fakta yang muncul echo sys_get_temp_dir() . PHP_EOL;kembali /tmp. Juga, echo ini_get('upload_tmp_dir');tidak mengembalikan apa pun.

Untuk memverifikasi bahwa file yang diunggah sebenarnya muncul sebentar di /tmpfolder saya , saya menambahkan sleep(30);pernyataan ke skrip saya (seperti yang disarankan di sini ) dan menavigasi ke /tmpfolder saya di cPanel File Manager untuk menemukan file. Namun, apa pun itu, file yang diunggah tidak ditemukan di sana.

Saya menghabiskan waktu berjam-jam untuk menentukan alasannya, dan menerapkan setiap saran yang ditawarkan di sini.

Akhirnya, setelah mencari file situs web saya untuk kueri tmp, saya menemukan bahwa situs saya berisi folder lain yang disebutkan tmpdalam direktori berbeda. Saya menyadari bahwa skrip PHP saya sebenarnya sedang menulis file yang diunggah .cagefs/tmp. ( "Tampilkan File Tersembunyi" harus diaktifkan di cPanel untuk melihat folder ini.)

Jadi, mengapa sys_get_temp_dirfungsi mengembalikan info yang tidak akurat?

Berikut adalah penjelasan dari halaman web PHP.net untuk sys_get_temp_dir(yaitu, komentar teratas):

Jika berjalan pada sistem Linux di mana systemd memiliki PrivateTmp = true (yang merupakan default pada CentOS 7 dan mungkin distro baru lainnya), fungsi ini hanya akan mengembalikan "/ tmp", bukan jalan yang benar, lebih lama, agak dinamis.

Posting SO ini menggali masalah, juga:

Jangkrik
sumber
0

Saya mendapat masalah yang sama dan tidak ada tema yang merupakan kesalahan saya. Periksa di file .htaccess Anda, jika ada, jika "MultiViews" diaktifkan. Saya harus menonaktifkannya.

Murolack
sumber
0

Saya memiliki masalah yang sama dan masalah ini bernilai salah dalam htaccess seperti yang disebutkan shamittomar.

Ubah php_value post_max_size 10MBkephp_value post_max_size 10M

Johnny Vietnam
sumber
0

Saya kosong $_FILESkarena setelah <form enctype="multipart/form-data" method="post">saya tempatkan

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

Seperti kode awal

<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>

Saya memutuskan untuk memodifikasi dan

<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>

Jadi kesimpulannya adalah bahwa setelah <form enctype="multipart/form-data" method="post">harus <input name, type, iddan tidak boleh <div>atau tag lain

Dalam situasi saya, kode yang benar adalah

<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>
Andris
sumber
0

Saya juga punya masalah dengan $ _FILES kosong. Daftar periksa di atas tidak menyebutkan MultiViews di .htaccess, httpd.conf atau httpd-vhost.conf.

Jika Anda memiliki MultiViews diatur dalam direktif pilihan untuk direktori Anda yang berisi situs web, $ _FILES akan kosong, meskipun tajuk Panjang Konten jika menunjukkan bahwa file yang saya unggah.

gerteb
sumber
0

Jika Anda menggunakan JQuery Mobile

Menggunakan formulir multi-bagian dengan input file tidak didukung oleh Ajax. Dalam hal ini Anda harus menghias formulir induk dengan data-ajax = "false" untuk memastikan formulir dikirimkan dengan benar ke server.

<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>
Rajan
sumber
0

Lepaskan formulir Anda dari halaman yang Anda gunakan menjadi halaman php sederhana yang hanya memiliki formulir dan kode php, dan ujilah seperti itu.

Bootstrap atau skrip java apa pun dapat membersihkan _FILES []. Itu kasus saya

pengguna2195463
sumber