Em um projeto php que estou desenvolvendo me deparei com alguns requisitos onde tinha que disponibilizar ao usuário a opção de enviar arquivos(fotos, documentos, etc) para o servidor através da interface do próprio sistema. Pois bem, mas como existia essa necessidade em diversos lugares nada melhor que criar uma função específica para o upload de arquivos e chamá-la sempre que necessário.
E no post de hoje vou compartilhar essa função com vocês, abordando o funcionamento dela e ensinando a utilizar.
Pra começar, vamos criar uma estrutura de arquivos da seguinte maneira:
- index.php
- upload.php
- funcao_upload.php
- pasta_uploads
No arquivo principal(index) é onde colocaremos o formulário para selecionar o arquivo a ser enviado. O upload.php receberá as informações desse formulário, definirá os parâmetros e executará a função em si que estará implementada dentro do arquivo funcao_upload.php. Além desses 3 arquivos, criaremos também uma pasta chamada pasta_uploads que é o local onde os arquivos serão salvos.
Certo. Vamos aos códigos. Primeiro vamos criar a função(no arquivo funcao_upload.php):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | <?php /** * Função para fazer upload de arquivos * @author Rafael Wendel Pinheiro * @param File $arquivo Arquivo a ser salvo no servidor * @param String $pasta Local onde o arquivo será salvo * @param Array $tipos Extensões permitidas para o arquivo * @param String $nome Nome do arquivo. Null para manter o nome original * @return array */ function uploadFile($arquivo, $pasta, $tipos, $nome = null){ if(isset($arquivo)){ $infos = explode(".", $arquivo["name"]); if(!$nome){ for($i = 0; $i < count($infos) - 1; $i++){ $nomeOriginal = $nomeOriginal . $infos[$i] . "."; } } else{ $nomeOriginal = $nome . "."; } $tipoArquivo = $infos[count($infos) - 1]; $tipoPermitido = false; foreach($tipos as $tipo){ if(strtolower($tipoArquivo) == strtolower($tipo)){ $tipoPermitido = true; } } if(!$tipoPermitido){ $retorno["erro"] = "Tipo não permitido"; } else{ if(move_uploaded_file($arquivo['tmp_name'], $pasta . $nomeOriginal . $tipoArquivo)){ $retorno["caminho"] = $pasta . $nomeOriginal . $tipoArquivo; } else{ $retorno["erro"] = "Erro ao fazer upload"; } } } else{ $retorno["erro"] = "Arquivo nao setado"; } return $retorno; } ?> |
A função uploadFile recebe como parâmetro o arquivo a ser salvo, a pasta onde será salvo, os tipos de extensões permitidos e o novo nome do arquivo(caso deseje mudar. Se não, ele continua com o nome original).
Entendendo a função:
Primeiro verifica se o arquivo foi carregado no formulário. Então ele cria uma variável $infos que é um array que receberá os valores do nome do arquivo separados por ponto(Ex: Um arquivo com o nome minha_foto.jpg é salvo como $infos[0] => “minha_foto”, $infos[1] => “jpg”. O arquivo com nome foto.ferias.1.jpg é salvo como $infos[0] => “foto”, $infos[1] => “ferias”, $infos[2] => “1”, $infos[3] => “jpg”). Esse processo é para tratar a extensão do arquivo e em um segundo momento verificar se é uma extensão válida ou não.
Agora é feita uma verificação na variável $nome para ver se o usuário deseja manter o mesmo nome para o arquivo ou deseja renomeá-lo. Se desejar manter o nome original ele vai percorrer o array $infos para novamente formar o nome. Só que agora deixando a última posição(no caso a extensão do arquvo) de fora. Ou seja, o nome que antes era foto.ferias.1.jpg agora será foto.ferias.1. (o último carcater será um ponto).
Seguindo a função, a variável $tipoArquivo vai pegar a extensão do arquivo(que está na última posição do array $infos) e verificar se é uma extensão permitida. Se for, ele move o arquivo para a pasta definida e retorna o caminho desse arquivo. Caso ocorra erros em algum momento ele será retornado ao fim da função.
Com a função feita, veremos agora como utilizá-la. Vamos criar no nosso arquivo index.php o formulário HTML para selecionar um arquivo:
1 2 3 4 5 6 7 8 9 10 11 12 | <html> <head> <title>Upload de fotos</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> </head> <body> <form name="form1" method="post" action="upload.php" enctype="multipart/form-data"> Arquivo: <input type="file" name="arquivo" /><br> <input type="submit" value="Enviar ao servidor"/> </form> </body> </html> |
Note que na action do meu formulário eu defini que o carregamento do mesmo deverá ser no arquivo upload.php
É nesse arquivo que eu vou chamar a função e logicamente enviar o arquivo selecionado para o servidor.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <?php require_once('funcao_upload.php'); $arquivo = $_FILES['arquivo']; $tipos = array('jpg', 'png', 'jpeg', 'psd'); //só permite imagens $verifica = uploadFile($arquivo, 'pasta_uploads/', $tipos, 'novo_nome_do_arquivo'); if($verifica['erro']){ echo $verifica['erro']; } else{ echo "Upload efetuado com sucesso. Arquivo salvo em " . $verifica['caminho']; } ?> |
Importo o arquivo onde a função está implementada. Depois jogo as informações do arquivo dentro da variável $arquivo. Considerando que nesse formulário pode-se fazer apenas uploads de imagens, eu defino as extensões permitidas dentro da variável $tipos. Executo a função passando os parâmetros corretamente (note que defini um novo nome para o meu arquivo) e por fim faço uma verificação e exibo o alerta de sucesso/erro na tela.
Espero que essa função lhe seja útil tanto quanto ela é para mim. E lembre-se que nada te impede de aprimorá-la.
Abs.
Siga-me no twitter: @rafaelwendel
Muito bom ! Funcionou de primeira ! Obrigado !
Olá Trevisan,
Que bom que pude ajudar.
Espero sua visita mais vezes.
Abs
Valeu garoto, rodou de prima tbm !
abraços
Que bom que funcionou João Ricardo
Valeu pela visita
Abs
Gostaria de saber qual variável retorna o nome do arquivo, para que seja salvo o nome no banco de dados junto com a extensão
Juliano, no exemplo do post, para ver o caminho do arquivo é $verifica[‘caminho’]
Abs
No texto do video diz que se quisermos alterar o nome da imagem ele pede um nome para o usuario, aqui ele nao fez isso, somente renomeia para novo_nome_do_arquivo.jpg,
se eu enviar 2 imagens ele sobrescreve, como ficaria uma alteracao rapida e simples para ele gerar nomes em sequencia.
ex.
imagem1.jpg
imagem2.jpg
imagem3.jpg
?
Obrigado
Olá Alex,
Uma maneira de fazer com que as imagens tenham nomes únicos é gerando uma string criptografada.
Ex: $nome_img = md5(date(‘Ymdhis’));
Aí você passa o $nome_img como parâmetro na função.
No caso acima ele vai criptografar uma string gerada com o ano/mês/dia/hora/minuto/segundo
Logo, nunca teremos duas imagens com o mesmo nome.
Qualquer dúvida mande outro comentário.
Abs
com um pouco de esforço e com sua ajuda até arquivo em pdf conseguir hehehe
muito bom mesmo!
Ajudou muitoo em Brother Valeuuu mesmo continua postando 😀
Rafael, achei ótimo e funciona bem, só não consegui rodar no iexplorer, no firefox roda 100%.
No Iexplorer não aparece a barra de progresso, e a contagem fica em “0%” e quando termina o upload mostra “100%”, não existe contagem intermediária.
Existe uma maneira de se corrigir isso?
Obrigado!
Olá,
Como eu poderia implantar mais filtros nessa função.
Gostaria de limitar o tamanho a 150 kb e as medidas a 368×60.
Mexi aqui, mas começou a dar erro.
Parabéns! Muito didático. Ótima ajuda!
Meu brother como fazer para os arquivos ir para o banco de dados com o mesmo nome salvo na pasta, e não array?
Gabriel,
Depois de fazer o upload, faça um insert no banco de dados salvando o $verifica[‘caminho’]
Abs!
Olá Rafael, li seu post e gostei muito, porem estou precisando de ajuda no desenvolvimento de um formulario de envio semelhante a esse seu para enviar dados de um cadastro (nome, telefone..etc ) e tambem enviar um arquivo pra determinada pasta do servidor, tipo uma foto, ou um curriculo, por exemplo. E eu nao estou conseguindo fazer isso sozinha… sera que vc poderia me ajudar??
aguardo sua resposta
Rafael,
Excelente publicação, parabéns!!!
Olha só, eu já tenho uma tabela com os campos já definidos no BD para receber os arquivos que o usuário fará o upload.
Por exemplo, no meu caso eu preciso que o usuário faça o envio de dois arquivos, o comprovante de pagamento e o contrato digitalizado (ambos podem ser imagem ou pdf), a tabela é usuarios, ela contem os campos cod_usu, nome_usu….. comprovante_usu e contrato_usu, esses dois campos receberão os arquivos do usuário.
É possível receber esses arquivos no BD, pra essa tabela e ainda numa pasta com o nome de cada usuário que faça o upload dos arquivos?
Se sim, como você sugere isso?
Olá Rubens,
Quando é assim eu faço o seguinte:
1. Crio uma pasta com o ID do usuário
2. Faço o upload dos arquivos para essa pasta
3. Salvo no banco o caminho dos arquivos
Isso te ajuda?
Abs!
Ola Rafael, estou tentando fazer uploads de pdf, ele faz o upload mas aponta um erro na linha 10 do código do arquivo upload.php, mas salva.
quando vou abrir aparece que o pdf esta corrompido a que se deve esse problema ?