Manipulando dados de formulários com PHP – Parte 2 (Upload de Arquivos)
3 - Verificando e limitando os arquivos enviados
3.1 - Tamanho dos arquivos
Existem várias formas de verificar o tamanho de arquivo enviado.
- A primeira limitação que você pode impor nos uploads é colocar o seguinte campo em seu formulário:
Essa diretiva diz ao navegador o tamanho máximo de arquivo que pode ser enviado, onde o valor fornecido deve ser em bytes. Mas, é fácil contornar este limite, então não conte que o navegador irá obedecer a sua vontade. Mas você deve adicionar MAX_FILE_SIZE em qualquer caso, já que salva os usuários do problema de esperar por um grande arquivo ser transferido e somente depois de tudo descobrir que ele é muito grande.
- Verificando com a variável $_FILES['arquivo']['size'], onde no seu script haverá por exemplo um if:
- Verificando com a variável $_FILES['arquivo']['error']:
Ao enviar um formulário de upload, a variável $_FILES['arquivo']['error'] poderá conter os seguintes valores:
UPLOAD_ERR_OK
Valor: 0; não houve erro, o upload foi bem sucedido.
UPLOAD_ERR_INI_SIZE
Valor 1; O arquivo no upload é maior do que o limite definido em upload_max_filesize no php.ini.
UPLOAD_ERR_FORM_SIZE
Valor: 2; O arquivo ultrapassa o limite de tamanho em MAX_FILE_SIZE que foi especificado no formulário html.
UPLOAD_ERR_PARTIAL
Valor: 3; o upload do arquivo foi feito parcialmente.
UPLOAD_ERR_NO_FILE
Valor: 4; Não foi feito o upload do arquivo.
Então, assuma que seu formulário de upload seja:
E o visitante faça um upload de um arquivo maior que o especificado em MAX_FILE_SIZE e maior que o da configuração upload_max_filesize. Seu script PHP (no caso script2.php), conterá as seguintes verificações:
3.2 - Tipo dos arquivos
Assuma que você possui um site com a área de usuários, onde os mesmos possam enviar suas fotos. O tipo de imagem aceita seria apenas PNG. Mas, como sempre tem os "engraçadinhos" que possam acabar a enviando arquivos não-imagem, você então deve verificar se o arquivo é uma imagem. Para isso, você pode verificar a extensão do nome de arquivo ou o tipo de arquivo.
Mas, conforme expliquei em meu artigo, "Upload de Imagens com Segurança", verificar a extensão do nome de arquivo não é seguro (leia o artigo citado para mais informações), então o melhor é sempre verificar o mime tipo do arquivo. Para isso, usa-se então a variável $_FILES['arquivo']['type'] criada no upload de um arquivo.
No nosso exemplo, onde aceitamos apenas imagens PNG o mime tipo é: image/png.
O script que verificaria isso:
Obs: Caso aceite mais tipos de arquivos, use expressões regulares na verificação. Há um exemplo disso no meu artigo "Upload de Imagens com Segurança".
3.3 - Nome dos arquivos
Vamos continuar com o nosso exemplo onde os usuários enviam suas fotos. Usuários podem acabar enviando arquivos com nomes com espaços, várias letras maiúsculas e minúsculas, etc... É recomendável você definir um padrão para os nomes de arquivos e o melhor é sempre colocar underscores ( _ ) no lugar de espaços e que todas as letras sejam minúsculas.
Assuma também que todas as fotos são salvas no mesmo diretório. Isso tem a falha de fotos de usuários acabarem ficando com o mesmo nome e se sobrescreverem, então 2 usuários diferentes tendo a mesma foto! Você pode verificar se o arquivo com mesmo nome já existe no diretório ou usar uma função que gera nomes únicos para a imagem. Aqui irei mostrar apenas a verificação do diretório, o nome único há no meu artigo "Upload de Imagens com Segurança".
Então é isso! Foi dada uma ampla explicação sobre os uploads de arquivos com o PHP. Futuramente estarei publicando um artigo explicando o upload de múltiplos arquivos direto do mesmo formulário.
Obs: Alguns textos e códigos foram pegos do Manual Oficial do PHP:
http://www.php.net/manual/pt_BR/features.file-upload.php
Obs2: Há uma lista ampla de Mime-Types aqui:
http://www.auriumsoft.com.br/mime_types.html
Até a próxima!
Alfred Reinold Baudisch
alfred.baudisch@gmail.com
Blog: http://www.auriumsoft.com.br/blog/
Auriumsoft :: Inteligência, Tecnologia e Vídeo
http://www.auriumsoft.com.br
Auriumsoft Hosting
http://www.auriumhost.com.br
3.1 - Tamanho dos arquivos
Existem várias formas de verificar o tamanho de arquivo enviado.
- A primeira limitação que você pode impor nos uploads é colocar o seguinte campo em seu formulário:
<input type="hidden" name="MAX_FILE_SIZE" value="30000">
Essa diretiva diz ao navegador o tamanho máximo de arquivo que pode ser enviado, onde o valor fornecido deve ser em bytes. Mas, é fácil contornar este limite, então não conte que o navegador irá obedecer a sua vontade. Mas você deve adicionar MAX_FILE_SIZE em qualquer caso, já que salva os usuários do problema de esperar por um grande arquivo ser transferido e somente depois de tudo descobrir que ele é muito grande.
- Verificando com a variável $_FILES['arquivo']['size'], onde no seu script haverá por exemplo um if:
<?php // Tamanho máximo do arquivo em bytes $maximo = 50000; // Verificação if ($_FILES['arquivo']['size'] > $maximo) { echo "Erro! O arquivo enviado por você ultrapassa o limite máximo de " . $maximo . " bytes! Envie outro arquivo"; } ?>
- Verificando com a variável $_FILES['arquivo']['error']:
Ao enviar um formulário de upload, a variável $_FILES['arquivo']['error'] poderá conter os seguintes valores:
UPLOAD_ERR_OK
Valor: 0; não houve erro, o upload foi bem sucedido.
UPLOAD_ERR_INI_SIZE
Valor 1; O arquivo no upload é maior do que o limite definido em upload_max_filesize no php.ini.
UPLOAD_ERR_FORM_SIZE
Valor: 2; O arquivo ultrapassa o limite de tamanho em MAX_FILE_SIZE que foi especificado no formulário html.
UPLOAD_ERR_PARTIAL
Valor: 3; o upload do arquivo foi feito parcialmente.
UPLOAD_ERR_NO_FILE
Valor: 4; Não foi feito o upload do arquivo.
Então, assuma que seu formulário de upload seja:
<form action="script2.php" method="POST" enctype="multipart/form-data"> <input type="hidden" name="MAX_FILE_SIZE" value="30000"> Arquivo: <input name="arquivo" type="file"><BR> <input type="submit" value="Enviar"> </form>
E o visitante faça um upload de um arquivo maior que o especificado em MAX_FILE_SIZE e maior que o da configuração upload_max_filesize. Seu script PHP (no caso script2.php), conterá as seguintes verificações:
<?php // Tamanho ultrapassa o MAX_FILE_SIZE do formulário if ($_FILES["arquivo"]["error"] == UPLOAD_ERR_FORM_SIZE) { echo "O tamanho de seu arquivo ultrapassa o limite dado! Envie outro arquivo"; exit; } // Tamanho ultrapassa o limite da configuração upload_max_filesize do php.ini if ($_FILES["arquivo"]["error"] == UPLOAD_ERR_INI_SIZE) { echo "O tamanho de seu arquivo ultrapassa o limite de tamanho de arquivo do PHP! Envie outro arquivo"; exit; } ?>
3.2 - Tipo dos arquivos
Assuma que você possui um site com a área de usuários, onde os mesmos possam enviar suas fotos. O tipo de imagem aceita seria apenas PNG. Mas, como sempre tem os "engraçadinhos" que possam acabar a enviando arquivos não-imagem, você então deve verificar se o arquivo é uma imagem. Para isso, você pode verificar a extensão do nome de arquivo ou o tipo de arquivo.
Mas, conforme expliquei em meu artigo, "Upload de Imagens com Segurança", verificar a extensão do nome de arquivo não é seguro (leia o artigo citado para mais informações), então o melhor é sempre verificar o mime tipo do arquivo. Para isso, usa-se então a variável $_FILES['arquivo']['type'] criada no upload de um arquivo.
No nosso exemplo, onde aceitamos apenas imagens PNG o mime tipo é: image/png.
O script que verificaria isso:
<?php // Verifica se o mime-type é de imagem PNG if ($_FILES['arquivo']['type'] !== "image/png") { echo "O arquivo enviado por você não é uma imagem PNG! Envie outro!"; } ?>
Obs: Caso aceite mais tipos de arquivos, use expressões regulares na verificação. Há um exemplo disso no meu artigo "Upload de Imagens com Segurança".
3.3 - Nome dos arquivos
Vamos continuar com o nosso exemplo onde os usuários enviam suas fotos. Usuários podem acabar enviando arquivos com nomes com espaços, várias letras maiúsculas e minúsculas, etc... É recomendável você definir um padrão para os nomes de arquivos e o melhor é sempre colocar underscores ( _ ) no lugar de espaços e que todas as letras sejam minúsculas.
Assuma também que todas as fotos são salvas no mesmo diretório. Isso tem a falha de fotos de usuários acabarem ficando com o mesmo nome e se sobrescreverem, então 2 usuários diferentes tendo a mesma foto! Você pode verificar se o arquivo com mesmo nome já existe no diretório ou usar uma função que gera nomes únicos para a imagem. Aqui irei mostrar apenas a verificação do diretório, o nome único há no meu artigo "Upload de Imagens com Segurança".
<?php // Repassa a variável do upload $arquivo = isset($_FILES['arquivo']) ? $_FILES['arquivo'] : FALSE; // Código acima... com as demais verificaçoes... // Diretório para onde o arquivo será movido $diretorio = "./arquivos/"; // Substitui espaços por underscores no nome do arquivo $nome = str_replace(" ", "_", $arquivo["name"]); // Todas as letras em minúsculo $nome = strtolower($nome); // Caminho completo do arquivo $nome = $diretorio . $nome; // Verifica se o arquivo existe no diretório dado if (file_exists($nome)) { echo "Um arquivo com esse nome já foi enviado! Envie outro arquivo!"; exit; } // Tudo ok! Então, move o arquivo if (move_uploaded_file($arquivo['tmp_name'], $nome)) { echo "Arquivo Enviado com sucesso!"; } else { echo "Erro ao enviar seu arquivo!"; } ?>
Então é isso! Foi dada uma ampla explicação sobre os uploads de arquivos com o PHP. Futuramente estarei publicando um artigo explicando o upload de múltiplos arquivos direto do mesmo formulário.
Obs: Alguns textos e códigos foram pegos do Manual Oficial do PHP:
http://www.php.net/manual/pt_BR/features.file-upload.php
Obs2: Há uma lista ampla de Mime-Types aqui:
http://www.auriumsoft.com.br/mime_types.html
Até a próxima!
Alfred Reinold Baudisch
alfred.baudisch@gmail.com
Blog: http://www.auriumsoft.com.br/blog/
Auriumsoft :: Inteligência, Tecnologia e Vídeo
http://www.auriumsoft.com.br
Auriumsoft Hosting
http://www.auriumhost.com.br
Bom eu estou com o seguinte problema eu to querendo pegar o arquivo que o usuario coloca e copiá-lo no servidor nao funciona e qndo eu vou entrar no tmp do para ver se tinha criado se quer um arquivo temporario tb nao criou?O que ta acontecendo?Alguem podia me dar um help please.
08/08/2007 8:48pm
(~17 anos atrás)
Cara, era o que eu precisava, porem eu preciso que dos dados do form seja cadastrado no mysql pq eh um controle de relatorios, e os pdfs vão pra uma pasta pro meu cliente acessar, e existem várias páginas, cada pdf pertence a uma pastas... meio complicado neh..
imagina assim... pdf1.pdf - pdf2.pdf - pdf3.pdf
pasta 1 - pdf2.pdf
pasta 2 - pdf1.pdf
pasta 3 - pdf3.pdf
ae qdo der o submit no form eu envio o pdf para pasta dele entendeu??
Tbm tem o casa de não ter a pasta e ela precisar ser criada...
ficou complexa a historia e ae eu parei...
Valeu desde já...
imagina assim... pdf1.pdf - pdf2.pdf - pdf3.pdf
pasta 1 - pdf2.pdf
pasta 2 - pdf1.pdf
pasta 3 - pdf3.pdf
ae qdo der o submit no form eu envio o pdf para pasta dele entendeu??
Tbm tem o casa de não ter a pasta e ela precisar ser criada...
ficou complexa a historia e ae eu parei...
Valeu desde já...
14/05/2007 12:34pm
(~17 anos atrás)
Uso o mysql aqui,,
MAnipulo o banco pelo myadmin
Como eu faria para guardar direto em um campo do meu banco de dados esse arquivo?
Qq coisa, desculpe-me a ignorância, sou novato no php.Um abraço a todos
MAnipulo o banco pelo myadmin
Como eu faria para guardar direto em um campo do meu banco de dados esse arquivo?
Qq coisa, desculpe-me a ignorância, sou novato no php.Um abraço a todos
05/04/2007 11:59pm
(~17 anos atrás)
O código funcionou perfeitamente no servidor windows, mas no servidor linux é preciso colocar a funcação CHMOD após de ter feito upload da imagem para o servidor para que você possa ter permissão de execução no arquivo.
chmod("/DIRETÓRIO/ARQUIVO",0777);
chmod("/DIRETÓRIO/ARQUIVO",0777);
11/10/2005 8:35am
(~19 anos atrás)
Eu conseguir configurar direitinho, o arquivos está sendo mandado para a pasta selecionada. Mas queria que vc postasse codigo php onde os arquivos envidos seriam mostrados automaticamente numa página.
Ex: o cara mandou um arquivos para a pasta Animes, aí o arquivo enviado seria mostrado na pagina Animes do meu site automaticamente, mostrando o nome, descrição, tamanho entre outros.
Pq tem q ficar adicionando um por um é um saco, queria um automatico, pelo amor de deus me ajudeeeeemmmm
Ex: o cara mandou um arquivos para a pasta Animes, aí o arquivo enviado seria mostrado na pagina Animes do meu site automaticamente, mostrando o nome, descrição, tamanho entre outros.
Pq tem q ficar adicionando um por um é um saco, queria um automatico, pelo amor de deus me ajudeeeeemmmm
20/06/2005 7:35pm
(~19 anos atrás)
Existe alguma forma de exibir o conteúdo do arquivo (foto ou conteúdo do texto) no script sem salvar no servidor????
14/04/2005 5:03pm
(~19 anos atrás)
Bom dia Alfred,
já realizo upload de arquivos, no entanto, pintou uma nova necessidade, a de realizar múltiplos uploads, no entanto, não quero selecionar arquivo a arquivo e sim um diretório inteiro. Vc saberia como posso fazer isso e, claro, se é possível.
de antemão, agradeço a atenção dispensada.
Att,
Luiz Lima
já realizo upload de arquivos, no entanto, pintou uma nova necessidade, a de realizar múltiplos uploads, no entanto, não quero selecionar arquivo a arquivo e sim um diretório inteiro. Vc saberia como posso fazer isso e, claro, se é possível.
de antemão, agradeço a atenção dispensada.
Att,
Luiz Lima
04/01/2005 6:32am
(~20 anos atrás)
Gastão,
Para upload não são usados nenhum módulo / extensão do PHP. É algo na engine do PHP. Que erro está obtendo?
Para upload não são usados nenhum módulo / extensão do PHP. É algo na engine do PHP. Que erro está obtendo?
21/12/2004 8:22am
(~20 anos atrás)
A questão é, se eu for acompanhar o seu formulario é claro que da certo.
Mais na realidade na pratica não está funcionado pois tenho uma pagina com as seguinte situação:
<form name="genericos" method="post" action="" enctype="multipart/form-data">
<label>
<span>Link PDF:</span>
<input type="text" name="link_pdf" />
</label>
<label>
<span>Upload do arquivo em PDF:</span>
<input type="file" name="up_pdf[]" class="file" />
</label>
<br /><br />
<label>
<span>Link Excel:</span>
<input type="text" name="link_excel" />
</label>
<label>
<span>Upload do arquivo em Excel:</span>
<input type="file" name="up_excel[]" class="file" />
</label>
<br /><br />
<label>
<span>Upload da Imagem Logo:</span>
<input type="file" name="up_logo[]" class="file" />
</label>
<input type="submit" name="salvar" id="salvar" value="Salvar" class="btn" />
</form>
Veja que tem 3 upload de imagem para fazer e 4 link sendo 2 em .pdf. e 2 em .xml.
Agora sou iniciante em programação então uma duvida.
Quanto vc sita "" $_FILES['arquivo'] "" a apalavra "arquivo" seria o que exatamente na minha situação, acredito que seria os ex: "" name="up_excel[]" "" ou não...
Como eu coloco esse script para fazer a minha pagina enviar uma imagem, 4 link, e 4 arquivos de documentos.
Obrigado por compartilhar.