Perché $ _FILES dovrebbe essere vuoto quando si caricano file su PHP?


145

Ho WampServer 2 installato sul mio computer Windows 7. Sto usando Apache 2.2.11 e PHP 5.2.11. Quando provo a caricare qualsiasi file da un modulo, sembra caricarlo, ma in PHP l' $_FILESarray è vuoto. Non ci sono file nella c:\wamp\tmpcartella. Ho configurato php.iniper consentire il caricamento di file e simili. La tmpcartella ha i privilegi di lettura / scrittura per l'utente corrente. Sono perplesso.

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
Hai controllato i log degli errori?
Byron Whitlock,

Sono sicuro che c'è qualcosa di stupido che stai trascurando. Ad esempio, sei sicuro di avere il codice vanilla-upload.php?
Luca Matteis,

Ah, stavo avendo lo stesso problema. Ho controllato i log degli errori e mi è stato detto che veniva caricato un file che superava la dimensione massima consentita.
BrightIntelDusk

Risposte:


493

Ecco una lista di controllo per il caricamento di file in PHP:

  1. Controlla php.ini per:
    file_uploads = On
    post_max_size = 100M
    upload_max_filesize = 100M

    • Potrebbe essere necessario utilizzare .htaccesso .user.inise si utilizza l'hosting condiviso e non si ha accesso a php.ini.
    • Assicurati di modificare il file ini corretto: utilizza la phpinfo()funzione per verificare che le impostazioni vengano effettivamente applicate.
    • Inoltre assicuratevi non lo fai misspell le dimensioni - dovrebbe essere 100M non 100MB .
  2. Assicurati che il tuo <form>tag abbia l' enctype="multipart/form-data"attributo. Nessun altro tag funzionerà, deve essere il tuo tag FORM. Ricontrolla che sia scritto correttamente . Ricontrolla che i dati multipart / form siano racchiusi tra virgolette dritte, non virgolette intelligenti incollate da Word o da un blog di siti Web (WordPress converte le virgolette diritte in virgolette angolari!). Se nella pagina sono presenti più moduli, assicurarsi che entrambi abbiano questo attributo. Digitarli manualmente o provare virgolette singole dritte digitate manualmente.

  3. Assicurarsi di non disporre di due campi del file di input con lo stesso nameattributo. Se hai bisogno di supportare più, metti le parentesi quadre alla fine del nome:

    <input type="file" name="files[]">
    <input type="file" name="files[]">
  4. Assicurati che le tue directory tmp e upload abbiano le corrette autorizzazioni di lettura + scrittura. La cartella di caricamento temporaneo è specificata nelle impostazioni PHP come upload_tmp_dir.

  5. Assicurarsi che la directory di destinazione del file e tmp / upload non contenga spazi.

  6. Assicurati di avere tutto <form>sulla tua pagina</form> tag vicini.

  7. Assicurati che il tuo tag FORM abbia method="POST" . Le richieste GET non supportano i caricamenti multipart / form-data.

  8. Assicurati che il tag di input del file abbia un attributo NAME. Un attributo ID NON è sufficiente! Gli attributi ID devono essere utilizzati nel DOM, non per i payload POST.

  9. Assicurati di non utilizzare Javascript per disabilitare il tuo <input type="file"> campo al momento dell'invio

  10. Assicurati di non annidare moduli come <form><form></form></form>

  11. Controlla la tua struttura HTML per tag non validi / sovrapposti come <div><form></div></form>

  12. Assicurati inoltre che il file che stai caricando non contenga caratteri non alfanumerici.

  13. Una volta ho passato ore a cercare di capire perché mi stesse succedendo all'improvviso. Si è scoperto che avevo modificato alcune delle impostazioni di PHP in .htaccess, e una di esse (non sono ancora sicuro di quale) stava causando il fallimento del caricamento e lo $_FILESsvuotamento.

  14. Potresti potenzialmente provare a evitare il carattere di sottolineatura ( _) name=""nell'attributo del <input>tag

  15. Prova a caricare file di dimensioni molto ridotte per restringere la dimensione del file.

  16. Controlla lo spazio disponibile su disco. Anche se molto raro, è menzionato in questo commento della pagina del manuale PHP :

    Se l'array $ _FILES all'improvviso diventa misteriosamente vuoto, anche se il modulo sembra corretto, è necessario controllare lo spazio su disco disponibile per la partizione della cartella temporanea. Nella mia installazione, tutti i caricamenti di file non sono riusciti senza preavviso. Dopo aver digrignato molto i denti, ho provato a liberare spazio aggiuntivo, dopo di che improvvisamente i file caricati hanno funzionato di nuovo.

  17. Assicurati di non inviare il modulo tramite una richiesta POST AJAX anziché una normale richiesta POST che causa il ricaricamento di una pagina. Ho esaminato tutti i punti dell'elenco precedente e alla fine ho scoperto che il motivo per cui la mia variabile $ _FILES era vuota era che stavo inviando il modulo utilizzando una richiesta POST AJAX. So che ci sono anche metodi per caricare file usando Ajax, ma questo potrebbe essere un motivo valido per cui il tuo array $ _FILES è vuoto.

Fonte di alcuni di questi punti:
http://getluky.net/2004/10/04/apachephp-_files-array-mysteriously-empty/


12
Forse la risposta "accettata" ha risolto il post originale, ma questa è la risposta che ho trovato più utile. In caso di dubbi, guarda l'origine vista dal browser. Selezionando ogni elemento in questo elenco e rintracciando all'indietro, ho trovato il mio errore in un posto inaspettato. Se stai affrontando un problema simile, credimi, probabilmente non è un bug in Apache. ;)
timo

3
Assicurarsi inoltre che l'elemento del modulo contenente l'input del file NON sia figlio di un altro elemento del modulo. ad es.<form><form><input type="file"></form></form>
sudee,

3
Wow! Grazie per questa lista. il mio problema era # 2. stavo chiamando $('#my-form')[0].reset();nel gestore di invio.
Gavin,

2
Grazie. nel mio caso il numero 7. enctype = "multipart / form-data" era il colpevole.
Thupten,

3
DUDE, sei un vero toccasana. Passo ore cercando di capire questo (2) era il mio problema ... Grazie!
Mike Q,

74

Per quanto riguarda l'HTML, sembra che tu abbia impostato correttamente quella parte. Hai già ilenctype="multipart/form-data" che è molto importante avere nel modulo.

Per quanto riguarda la php.iniconfigurazione, a volte sui sistemi php.iniesistono più file. Assicurati di modificare quello corretto. So che hai detto che hai configurato il tuo php.inifile per il caricamento dei file, ma hai anche impostato il tuo upload_max_filesizee post_max_sizein modo che sia più grande del file che stai tentando di caricare? Quindi dovresti avere:

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

La tua directory: "c:\wamp\tmp"ha entrambe le autorizzazioni di lettura e scrittura? Ti sei ricordato di riavviare Apache dopo aver apportato le php.inimodifiche?



4
+1: per riavviare il suggerimento del server Apache. Molti utenti Windows lo dimenticano.
Shamittomar,

36

È importante aggiungere enctype="multipart/form-data"al modulo, ad esempio

<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

Grazie a tutti per le varie risposte complete. Sono tutti molto utili. La risposta si è rivelata molto strana. Si scopre che PHP 5.2.11 non piace quanto segue:

post_max_size = 2G

o

post_max_size = 2048M

Se lo cambio in 2047M, il caricamento funziona.


17
Si noti che un valore così elevato è una vulnerabilità agli attacchi fuori spazio / ddos. Basta aggiungere questo in modo che le persone sappiano che è troppo, quando provano a copiare e incollare la soluzione. Ad ogni modo, 2 concerti richiederebbero un tempo di caricamento troppo lungo.
Manuel Arwed Schmidt,

Non troppo grande. Abbiamo clienti che caricano file nella gamma 1-3G abbastanza regolarmente. Poiché stanno caricando file sui propri server e sono server autorizzati IP, lo scambio è abbastanza normale e si limita a consentire a un client di utilizzare le proprie apparecchiature nel modo in cui lo desiderano. Pagano le bollette, nessun rischio per la sicurezza, nessun problema.
TheSatinKnight

8

Ho lo stesso problema a guardare 2 ore, è molto semplice controllare prima la configurazione del nostro server.

Esempio:

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

qualsiasi tipo di dimensione del file è :20mb, ma il nostro upload_max_sizeè sopra 20mbma l'array lo è null. La risposta è che la nostra post_max_sizedovrebbe essere maggiore di upload_max_filesize

post_max_size = 750M  
upload_max_filesize = 750M

6

Ecco un'altra causa che ho riscontrato: quando si utilizza JQuery Mobile e l'attributo del modulo data-ajax è impostato su true, l'array FILES sarà vuoto. Quindi imposta data-ajax su false.


5

Assicurati che l'elemento di input abbia un attributo "name". <input type="file" name="uploadedfile" />

Se questo manca, $ _FILES sarà vuoto.


4

Stavo lottando con lo stesso problema e testando tutto, non ottenendo la segnalazione degli errori e nulla sembrava essere sbagliato. Ho avuto error_reporting (E_ALL) Ma improvvisamente mi sono reso conto che non avevo controllato il registro di Apache e voilà! Si è verificato un errore di sintassi nello script ...! (un "}" mancante)

Quindi, anche se questo è qualcosa di evidente da verificare, può essere dimenticato ... Nel mio caso (linux) è a:

/var/log/apache2/error.log

3

Nessuno ha menzionato questo, ma mi ha aiutato e non molti posti in rete lo menzionano.

Assicurati che php.ini imposti la seguente chiave:

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

Dovrai verificare con il tuo host web se vogliono che tu usi un percorso file server assoluto. Dovresti essere in grado di vedere altri esempi di directory nel tuo file php.ini per determinarlo. Non appena l'ho impostato ho ottenuto valori nel mio oggetto _FILES.

Assicurati infine che la tua cartella tmp e ovunque tu stia spostando i file abbiano i permessi corretti in modo che possano essere letti e scritti.


2

Se si sta tentando di caricare un array di file quindi potrebbe essere necessario aumentare max_file_uploadsin php.inicui è impostazione predefinita per20

Nota : max_file_uploadsNON può essere modificato al di fuori di php.ini. Vedi PHP "Bug" # 50684


2

Un altro possibile colpevole sono i reindirizzamenti di apache. Nel mio caso avevo il httpd.conf di apache impostato per reindirizzare determinate pagine del nostro sito su versioni http e altre pagine su versioni https della pagina, se non lo fossero già. La pagina in cui avevo un modulo con un input di file era una delle pagine configurate per forzare ssl, ma la pagina designata come azione del modulo era configurata come http. Quindi la pagina avrebbe inviato il caricamento alla versione ssl della pagina dell'azione, ma apache lo stava reindirizzando alla versione http della pagina e i dati del post, incluso il file caricato, sarebbero andati persi.



1

Se il tuo script principale è http://Some_long_URL/index.phpattento a specificare l'URL completo (con esplicito index.phpe non solo http://Some_long_URL) nel actioncampo. Sorprendentemente, in caso contrario, viene eseguito lo script giusto, ma con en $ _FILES vuoti!


1

Ho riscontrato lo stesso problema e ho scoperto che era il mio IDE a far parte del problema. Stavo avviando il debugger direttamente dall'IDE (PHPStorm) invece di usare direttamente il browser. L'URL generato dall'IDE era così:

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

e semplicemente usando:

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

ha funzionato bene. La mia configurazione è PC / Windows 10 / WAMPSERVER 3.0.6 a 64 bit


stessa cosa qui, stavo correndo in cerchio per un'ora finora! grazie
EKanadily,

1

Non fidarti della posizione della cartella temporanea fornita da sys_get_temp_dir se ti trovi in ​​un ambiente di hosting condiviso.

Ecco un'altra cosa da verificare che non è ancora stata menzionata ...

Supponevo, naturalmente, che la cartella in cui il mio script PHP memorizzava i caricamenti di file temporanei fosse /tmp. Questa convinzione è stata rafforzata dal fatto che echo sys_get_temp_dir() . PHP_EOL;ritorna /tmp. Anche,echo ini_get('upload_tmp_dir'); non restituisce nulla.

Per verificare che il file caricato appaia brevemente nella mia /tmpcartella, ho aggiunto una sleep(30);dichiarazione al mio script (come suggerito qui ) e sono passato al mio/tmp cartella in cPanel File Manager per individuare il file. Tuttavia, qualunque cosa accada, il file caricato non si trovava da nessuna parte.

Ho trascorso ore a cercare di determinare il motivo di ciò e ho implementato tutti i suggerimenti offerti qui.

Alla fine, dopo aver cercato i file del mio sito Web per la query tmp, ho scoperto che il mio sito conteneva altre cartelle denominate tmpin directory diverse. Mi sono reso conto che il mio script PHP stava effettivamente scrivendo i file caricati su .cagefs/tmp. (Il "Mostra file nascosti" impostazione deve essere abilitata in cPanel per visualizzare questa cartella.)

Quindi, perché la sys_get_temp_dirfunzione restituisce informazioni inaccurate?

Ecco una spiegazione dalla pagina Web di PHP.net per sys_get_temp_dir(ovvero il commento principale):

Se in esecuzione su un sistema Linux in cui systemd ha PrivateTmp = true (che è l'impostazione predefinita su CentOS 7 e forse altre distribuzioni più recenti), questa funzione restituirà semplicemente "/ tmp", non il percorso vero, molto più lungo, in qualche modo dinamico.

Questo post SO approfondisce anche il problema:


0

Ho avuto lo stesso problema e nessuno dei temi era il mio errore. Controlla nel tuo file .htaccess, se ne hai uno, se "MultiViews" è abilitato. Ho dovuto disabilitarli.


0

Ho avuto un problema simile e il problema era errato in htaccess come menzionato shamittomar.

Cambia php_value post_max_size 10MBinphp_value post_max_size 10M


0

Ero vuoto $_FILESperché dopo l' <form enctype="multipart/form-data" method="post">ho piazzato

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

Il codice iniziale era come

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

Ho deciso di modificare e

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

Quindi la conclusione è che dopo <form enctype="multipart/form-data" method="post">deve essere <input name, type, ide non deve essere <div>o alcuni altri tag

Nella mia situazione il codice corretto era

<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

Anch'io ho avuto problemi con $ _FILES vuoti. La check-list sopra menzionata non menziona MultiView in .htaccess, httpd.conf o httpd-vhost.conf.

Se hai impostato MultiView nella direttiva opzioni per la tua directory contenente il sito web, $ _FILES sarà vuoto, anche se l'intestazione Content-Length se mostra che il file che ho caricato.


0

Se si utilizza JQuery Mobile

L'uso di un modulo multipart con un input di file non è supportato da Ajax. In questo caso è necessario decorare il modulo padre con data-ajax = "false" per assicurarsi che il modulo sia inviato correttamente al 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>

0

Stacca il modulo dalla pagina che stai utilizzando in una semplice pagina php che ha solo il modulo e il codice php e testalo in quel modo.

Qualsiasi bootstrap o script java potrebbe ripulire _FILES []. Quello era il mio caso

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.