Função php para upload de arquivos

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

É formado em Sistemas de Informação, pós-graduado em Sistemas de Banco de Dados e mestre em Educação com foco em Tecnologias Sociocomunitárias. Trabalha como professor de ensino técnico e tecnológico no Instituto Federal de Educação, Ciência e Tecnologia de São Paulo ministrando disciplinas nas áreas de programação, banco de dados, desenvolvimento de projetos e engenharia de software.

Posts relacionados

Comentários

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

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

  2. 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!

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

  4. 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?

  5. 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 ?

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *