web-dev-qa-db-pt.com

Por que $ _FILES estaria vazio ao carregar arquivos para o PHP?

Eu tenho o WampServer 2 instalado no meu computador com Windows 7. Estou usando o Apache 2.2.11 e o PHP 5.2.11. Quando eu tento fazer upload de qualquer arquivo de um formulário, ele parece fazer upload, mas no PHP, o array $_FILES está vazio. Não há arquivo na pasta c:\wamp\tmp. Eu configurei php.ini para permitir uploads de arquivos e tal. A pasta tmp tem privilégios de leitura/gravação para o usuário atual. Estou perplexo.

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";
?>
118
elmonty

Obrigado a todos pelas várias respostas abrangentes. Tudo isso é muito útil. A resposta acabou sendo algo muito estranho. Acontece que PHP 5.2.11 não gosta do seguinte:

post_max_size = 2G

ou 

post_max_size = 2048M

Se eu mudar para 2047M, o upload funciona.

14
elmonty

Aqui está uma lista de verificação para o upload de arquivos em PHP:

  1. Verifique o arquivo php.ini para:
    file_uploads = On
    post_max_size = 100M
    upload_max_filesize = 100M

    • Talvez seja necessário usar .htaccess ou .user.ini se você estiver em hospedagem compartilhada e não tiver acesso a php.ini.
    • Certifique-se de que Você está editando o arquivo ini correto - Use a função phpinfo() para verificar se as configurações de Estão sendo aplicadas. 
    • Verifique também se você não Digita errado os tamanhos. Deve ser 100Mnot100MB.
  2. Certifique-se de que sua tag <form> tenha o atributo enctype="multipart/form-data". Nenhuma outra tag funcionará, ela deve ser sua tag FORM. Verifique novamente se é escrito corretamente. Verifique se os dados de várias partes/formulário estão rodeados por citações STRAIGHT, não com citações inteligentes coladas do Word OR em um blog de site (o WordPress converte aspas diretas em cotações de ângulo!). Se você tiver vários formulários na página, verifique se ambos têm esse atributo. Digite-os manualmente ou tente aspas simples digitadas manualmente.

  3. Certifique-se de não ter dois campos de arquivo de entrada com o mesmo atributo name. Se você precisar de suporte múltiplo, coloque colchetes no final do nome:

    <input type="file" name="files[]">
    <input type="file" name="files[]">
    
  4. Certifique-se de que seus diretórios tmp e upload tenham as permissões de leitura + gravação corretas definidas. A pasta de upload temporária é especificada nas configurações PHP como upload_tmp_dir.

  5. Certifique-se de que seus diretórios de destino e tmp/upload de arquivo não possuam Espaços.

  6. Certifique-se de que todos os <form> na sua página tenham </form> tags de fechamento.

  7. Certifique-se de que sua tag FORM tenha method="POST". As solicitações GET não suportam uploads de dados de várias partes/formulários.

  8. Certifique-se de que sua tag de entrada de arquivo tenha um atributo NAME. Um atributo de ID não é suficiente! Os atributos de ID são para uso no DOM, não para cargas úteis POST.

  9. Verifique se você não está usando JavaScript para desativar seu campo <input type="file"> no envio

  10. Certifique-se de não aninhar formulários como <form><form></form></form>

  11. Verifique sua estrutura HTML em busca de tags inválidas/sobrepostas, como <div><form></div></form>

  12. Verifique também se o arquivo que você está enviando não contém caracteres não alfanuméricos.

  13. Certa vez, passei horas tentando entender por que isso estava acontecendo comigo de repente. Descobri que eu tinha modificado algumas das configurações PHP em .htaccess, e uma delas (não sei qual ainda) estava causando o upload falhar e $_FILES estar vazio.

  14. Você poderia tentar evitar sublinhados (_) no atributo name="" da tag <input>

  15. Tente fazer o upload de arquivos muito pequenos para restringir se é um problema de tamanho de arquivo.

  16. Verifique o seu espaço em disco disponível. Embora muito raro, é mencionado neste comentário de página do manual PHP :

    Se de repente o array $ _FILES ficar misteriosamente vazio, mesmo que seu formulário pareça correto, você deve verificar o espaço em disco disponível para sua partição de pasta temporária. Na minha instalação, todos os uploads de arquivos falharam sem aviso. Depois de muito ranger de dentes, tentei liberar espaço adicional, depois do qual os uploads de arquivos de repente funcionaram de novo.

  17. Verifique se você não está enviando o formulário por meio de uma solicitação AJAX POST em vez de uma solicitação POST normal que faz com que uma página seja recarregada. Eu passei por cada ponto na lista acima e, finalmente, descobri que o motivo pelo qual minha variável $ _FILES estava vazia era que eu estava enviando o formulário usando uma solicitação AJAX POST. Eu sei que existem métodos para fazer upload de arquivos usando ajax também, mas isso pode ser um motivo válido para a sua array $ _FILES estar vazia.

Fonte de alguns destes pontos:
http://getluky.net/2004/10/04/apachephp-_files-array-mysteriously-empty/

414
shamittomar

No que diz respeito ao HTML, parece que você configurou essa parte corretamente. Você já tem o enctype="multipart/form-data", que é muito importante ter no formulário.

No que diz respeito à sua configuração php.ini, às vezes existem vários arquivos php.ini em vários sistemas. Certifique-se de que você está editando o correto. Eu sei que você disse que configurou seu arquivo php.ini para fazer upload de arquivos, mas também definiu que upload_max_filesize e post_max_size sejam maiores do que o arquivo que você está tentando enviar? Então você deveria ter:

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

Seu diretório: "c:\wamp\tmp" tem permissões de leitura e gravação? Você se lembrou de reiniciar o Apache depois de fazer as alterações do php.ini?


67
Brian

É importante adicionar enctype="multipart/form-data" ao seu formulário, por exemplo

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

Aqui, outra causa que encontrei: Ao usar o JQuery Mobile e o atributo de formulário data-ajax está definido como true, a matriz FILES estará vazia. Então defina dados-ajax para false.

5
dutchman711

Eu tenho um mesmo problema olhando 2 horas, é muito simples para verificar a nossa configuração do servidor em primeiro lugar. 

Exemplo:

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

qualquer tipo de tamanho de arquivo é :20mb, mas nosso upload_max_size está acima de 20mb, mas array é null. A resposta é que nosso post_max_size deve ser maior que upload_max_filesize

post_max_size = 750M  
upload_max_filesize = 750M
5
shashik493

Eu estava lutando com o mesmo problema e testando tudo, não recebendo relatórios de erros e nada parecia estar errado. Eu tinha error_reporting (E_ALL) Mas de repente percebi que não havia verificado o log do Apache e voilà! Houve um erro de sintaxe no script ...! (um ausente "}")

Então, mesmo que isso seja algo evidente para ser verificado, pode ser esquecido ... No meu caso (linux) é em:

/var/log/Apache2/error.log
3
Luis Rosety

Certifique-se de que seu elemento de entrada tenha um atributo 'nome'. <input type="file" name="uploadedfile" />

Se isso estiver faltando, o $ _FILES estará vazio.

3
Adrian Parr

Outro possível culpado é o redirecionamento do Apache. No meu caso, eu tinha o httpd.conf do Apache configurado para redirecionar certas páginas em nosso site para versões http, e outras páginas para https versões da página, se já não estivessem. A página na qual eu tinha um formulário com uma entrada de arquivo era uma das páginas configuradas para forçar ssl, mas a página designada como a ação do formulário foi configurada para http. Assim, a página enviaria o upload para a versão ssl da página de ação, mas o Apache o redirecionava para a versão http da página e os dados da postagem, incluindo o arquivo enviado, eram perdidos.

2
user2723315

Se você estiver tentando fazer upload de uma matriz de arquivos, talvez seja necessário aumentar max_file_uploads in php.ini, que por padrão é definido como 20

Nota: max_file_uploads NÃO pode ser alterado fora do php.ini. Veja PHP "Bug" # 50684

2
Tahir Yasin

Verifique seu php.ini para enable_post_data_reading = On, porque:

Desativar esta opção faz com que $ _POST e $ _FILES não sejam preenchidos. A única maneira de ler postdata será através do php: // input stream wrapper. (...)

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

2
jmng

Ninguém mencionou isso, mas me ajudou e não muitos lugares na net mencionam isso.

Verifique se o seu php.ini define a seguinte chave:

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

Você precisará verificar com seu host da Web se eles quiserem que você use um caminho de arquivo de servidor absoluto. Você deve ser capaz de ver outros exemplos de diretório em seu arquivo php.ini para determinar isso. Assim que configuro, recebi valores no meu objeto _FILES.

Finalmente, certifique-se de que sua pasta tmp e onde quer que você esteja movendo os arquivos tenha as permissões corretas para que possam ser lidos e gravados.

2
AaronP

Eu me deparei com o mesmo problema e descobri que era meu IDE fazia parte do problema. Eu estava lançando o depurador diretamente do IDE (PHPStorm) em vez de apenas usar o navegador diretamente. O IDE URL gerado era assim:

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

e apenas usando:

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

funcionou muito bem. Minha configuração é PC/Windows 10/WAMPSERVER 3.0.6 64bit 

1
Marc M.

Eu tive problema semelhante e o problema estava em valor errado no htaccess como shamittomar mencionado.

Alterar php_value post_max_size 10MB para php_value post_max_size 10M

0
Johnny Vietnam

Se você estiver usando o JQuery Mobile

O uso de um formulário de várias partes com uma entrada de arquivo não é suportado pelo Ajax. Nesse caso, você deve decorar o formulário pai com data-ajax = "false" para garantir que o formulário seja enviado corretamente ao servidor.

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

Eu estava vazio $_FILES porque depois <form enctype="multipart/form-data" method="post"> eu coloquei 

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

Código inicial era como 

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

Eu decidi modificar 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>

Então, a conclusão é que depois de <form enctype="multipart/form-data" method="post"> deve ser <input name, type, id e não deve ser <div> ou algumas outras tags

Na minha situação, o código correto 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
Andris

Eu tenho o mesmo problema e nenhum tema foi o meu erro. Verifique no seu arquivo .htaccess, se você tiver um, se "MultiViews" estiver ativado. Eu tive que desativá-los.

0
Murolack

Se o seu script principal for http://Some_long_URL/index.php, tenha cuidado ao especificar o URL completo (com index.php e not only http://Some_long_URL explícitos) no campo action. Surpreendentemente, se não, o script correto é executado, mas com o $ _FILES vazio!

0
Gibbie

Eu também tive problemas com $ _FILES vazio. A lista de verificação acima não menciona os MultiViews em .htaccess, httpd.conf ou httpd-vhost.conf.

Se você tiver MultiViews definidos na diretiva de opções para o diretório que contém o site, $ _FILES estará vazio, mesmo que o cabeçalho Content-Length esteja mostrando que o arquivo foi carregado.

0
gerteb