- Como Criar Um Site, Blog – WebMaster.pt - http://www.webmaster.pt -

Upload De Arquivos Com PHP

Tweet [3]

Vocabulário: arquivos = ficheiros

Upload de arquivos. Não há muito a ser dito a não ser o que você precisa saber. Então vou parar de juntar frases e partir para os códigos.

Upload De Arquivos

Formulário Para Upload

Código básico HTML que permite ao usuário enviar uma imagem.


    <form action="upload-arquivo.php" method="post" enctype="multipart/form-data">
        <fieldset>
            <p><label for="Enviar arquivo">Enviar arquivo:</label></p>
            <input type="file" name="arquivo" class="width233" />
            <input type="submit" name="enviar" value="Enviar" />
        </fieldset>
    </form>

O elemento HTML utilizado para selecionar os arquivos a serem enviados é o file. Ele já vem com um botão embutido que oferece esta opção. Note que o name dele é “arquivo”.

Quando o formulário for enviar imagens, é necessário adicionar o atributo enctype. No nosso formulário ele tem o valor multipart/form-data para indicar que vamos enviar arquivos binários.

Tenha muita atenção na hora de programar para não esquecer do atributo enctype. Muitos fazem o script todo certo, mas esquecem dessa parte e perdem preciosos minutos. Se o arquivo não vai para o servidor e você não recebe mensagem de erro no navegador, são grandes as chances de você ter esquecido do enctype.

Código PHP

As informações enviadas pelo elemento file são armazenadas na array $_FILES[] do PHP. Supondo que enviamos uma imagem, veremos quais informações são fornecidas sobre ela.


<?php

$arquivo = $_FILES[‘arquivo’];
print_r($arquivo)

// Array
Array (
[name] => imagem.jpg
[type] => image/jpeg
[tmp_name] => C:\WINDOWS\Temp\php208.tmp
[error] => 0
[size] => 19189 )

?>

Na primeira linha a array $_FILES[] recebe as informações do campo nomeado “arquivo” do formulário. Em seguida para ver os dados contidos na array utilizamos o print_r.

O nome dos índices ajuda bastante a entender que informações eles guardam. São elas:

Nesse script eu resolvi criar uma variável para conter as informações do arquivo enviado. A idéia é tornar a digitação mais rápida e o código menor. Veja a diferença para acessar o índice name:


<?php

$_FILES[‘name’][‘arquivo’];
$arquivo[‘name’];

?>

Não existem certo ou errado, apenas jeitos diferentes de se atingir o mesmo objetivo. Os índices continuam os mesmos.

Restringindo O Tipo De Arquivo

O formulário que estamos criando é para o upload de imagens e vamos tratar o arquivo recebido como sendo uma. Mas e se o usuário envia um arquivo .pdf ou .exe? Como não estamos esperando isso, o código vai retornar um erro.

O índice type contém a declaração do tipo de arquivo que foi enviado, conhecido como mime-type. Através dele sabemos se foi enviado uma imagem, uma página web ou um arquivo de texto. A validação dos arquivos utilizando o type é mais indicada do que apenas checar qual a extensão do arquivo, pois esta pode ser trocada pelo usuário.

Uma imagem com extensão jpg, pode apresentar os seguintes mime-types:

Validar todos esses mime-types demora um tanto. Por isso vamos validar os mais comuns para imagens .jpg.


<?php
$arquivo = $_FILES['arquivo'];
if ($arquivo['type'] == "image/jpeg" || $arquivo['type']== "image/pjpeg")
{
  echo "Arquivo aceito.";  
} else{
  echo "Arquivo inválido. É permitido somente imagem com extensão .jpg.";
}

?>

Na primeira linha nós verificamos se o mime-type do arquivo enviado é jpeg ou pjpeg Se for mostramos uma mensagem de aceito, senão informamos que a imagem não é permitida.

Podemos validar outros tipos de arquivo como .png e .html com o mesmo procedimento. Acess uma lista completa de mime-types [4].

Limitar Tamanho Do Arquivo Enviado

O limite padrão estipulado pelo PHP para o tamanho dos arquivos que podem ser enviados para o servidor é de 2MB. Você pode alterar este valor nas configurações do PHP, mas vamos trabalhar com este limite de tamanho. Até porque, uma imagem deste tamanho, para utilização online, esta mais do que bom.


<?php
  if ($arquivo['size']>500000)
  {
    exit('Arquivo muito grande. Tamanho máximo permitido 500kb. O arquivo enviado contém '.round($arquivo['size']/1024).'kb');  
  }
?>

Na primeira linha criamos uma condição que diz: “Se o tamanho do arquivo é maior do que 50.000bytes” executar o código abaixo. As verificações de tamanho dos arquivos sempre serão feitas utilizando os valores em bytes.

Sendo o tamanho do arquivo maior do que 500kb retornamos uma mensagem, usando exit, para que o código pare de ser executado, informando o tamanho excessivo do arquivo. Também avisamos qual o tamanho do arquivo atual fazendo um pequeno cálculo que divide o tamanho do arquivo enviado por 1024 e arredonda o valor.

A divisão por 1024 ocorre porque 1kb é formado por 1024 bytes.

Podemos fazer a verificação de tipo de arquivo e tamanho utilizando apenas uma condicional. Mas no final das contas, para poder mostrar mensagens personalizadas, serão necessárias tantas linhas quanto as que utilizamos fazendo as verificações separadamente.

Nome Único

Tudo certo. Agora sabemos que foi enviada realmente uma imagem. Vamos trabalhar agora o nome do arquivo e torná-lo único. E por que isso?

A princípio para evitar conflito com arquivos já existentes no servidor com o mesmo nome. E também porque alguns clientes escrevem o nome dos arquivos com acentuação e isso pode gerar problema mais adiante se o nome das imagens for salvo em um banco de dados.


<?php

  $novonome = md5(mt_rand(1,10000).$arquivo['name']).'.jpg';

?>

Para criar o novo nome da imagem utilizamos a função mt_rand() que sorteia um número randômico entre 1 e 10000 e concatena ele com o nome da imagem. Em seguida empregamos a função md5 que embaralha os caracteres que recebe e por fim concatenamos as letras e números embaralhados com a string ‘.jpg’ para criar o nome do arquivo.

Enviando Para O Servidor


<?php

  $dir = "img/";
  if (!file_exists($dir))
  {
    mkdir($dir, 0755);  
  }
  $caminho = $dir.$novonome;
  move_uploaded_file($arquivo['tmp_name'],$caminho);

?>

A variável $dir recebe o nome da pasta para onde será enviado o arquivo. Pode ser pasta dentro de pasta, apenas cuide para que a string acabe com uma barra.

Se a pasta “img/” não existir, ela é criada com a função mkdir. Informamos o nome da pasta e já especificamos as permissões dela com o 0755, que permite a opção de escrita para a pasta. Esta segunda opção nem sempre é necessária, mas é aconselhável já que alguns servidores têm um rígido controle de permissões de pastas e arquivos.

Concatenamos o nome da pasta com o nome do arquivo para formar o caminho deste no servidor.

E por fim enviamos o arquivo para o servidor com a função move_uploaded_file. Ela aceita dois parâmetros, a localização temporária do arquivo no computador do usuário e o caminho completo para onde será enviada no servidor.

O código completo fica assim:


<?php

$arquivo = $_FILES['arquivo'];
if ($arquivo['type'] == "image/jpeg" || $arquivo['type']== "image/pjpeg")
{
  if ($arquivo['size']>500000)
  {
    exit('Arquivo muito grande. Tamanho máximo permitido 500kb. O arquivo enviado contém '.round($arquivo['size']/1024).'kb');  
  }
  
  $novonome = md5(mt_rand(1,10000).$arquivo['name']).'.jpg';
  $dir = "img/";
  if (!file_exists($dir))
  {
    mkdir($dir, 0755);  
  }
  $caminho = $dir.$novonome;
  move_uploaded_file($arquivo['tmp_name'],$caminho);
  echo '<script type="text/javascript">alert("Arquivo enviado!")</script>';
  echo '<meta http-equiv="refresh" content="1; url=index.html" />';  
} else{
  echo "Arquivo inválido. É permitido somente imagem com extensão .jpg.";
}

?>

Com algumas alterações no código acima, você pode validar e enviar todo tipo de arquivo.

DOWNLOAD: Descarregue o código utilizado neste tutorial para o Upload De Arquivos Com PHP [5], em formato .zip.

Tweet [3]
Be Sociable, Share!
  • [6]
  • [7]
  • [8]
  • [9]
  • [10]