[Resolvido] Upload Múltiplo de Imagens
Olá pessoal há alguns dias escrevi um tutorial explicando como funciona um upload múltiplo de imagens e o meu amigo Thiago Retondar me deu a idéia de publicar esse tutorial aqui no fórum, visto que sempre surge uma dúvida sobre esse assunto por aqui.
O tutorial não é nada complexo pelo contrário, é algo bem introdutório onde explico apenas o básico e o funcionamento de um upload múltiplo. Espero que todos gostem! :D
Tutorial original em -> OGordo.com // Um blog de peso
Talvez esse seja um dos assuntos que mais surgem dúvidas nos fóruns e nesse tutorial estarei demonstrando como é fácil realizar um upload múltiplo de imagens!
Então vamos ao que interessa!
O upload consiste em 4 arquivos: index.html, form_upload, upload.php e funções.php.
Primeiro precisamos criar a página index.html. Sua estrutura é bem simples, contém apenas um formulário com um único campo como este:
<form name="form" method="post" action="form_upload.php">
<label>
<span>Quantas imagens serão enviadas?</span>
<input name="qtd_campos" type="text" />
<input name="enviar" type="submit" value="Enviar" />
</label>
</form>
Veja que temos um campo chamado qtd_campos nele devemos inserir um valor, nesse caso é a quantidade de imagens que queremos enviar. A ação desse formulário é direcionada para o script form_upload.php.
Quando o formulário da index.html for submetido o responsável por capturar os valores será form_upload.php, ele tem a função de verificar se algum dado foi inserido na página anterior e fazer uma chamada a função gerarForm() que recebe dois parâmetros como mostrado logo abaixo:
//Inclui o arquivo contendo as duas funções da aplicação.
require('funcoes.php');
//Verifica se a superglobal $_POST possui algum valor, e se foi iniciada.
if(isset($_POST['qtd_campos']) && !empty($_POST['qtd_campos'])){
//Dois parâmetros são passados para a função, o primeiro é a quantidade de campos recebida do formulário o segundo é o máximo de campos permitidos para upload.
gerarForm($_POST['qtd_campos'], 5);
}else{
echo 'O formulário não foi preenchido corretamente!
<a href="javascript:history.go(-1)">Voltar</a>
';
}
A função gerarForm() esta localizada no arquivo funcoes.php e sua utilidade é gerar os campos do formulário para envio das imagens. Basicamente é uma função que produz dados de saída para o browser. Sua estrutura é a seguinte:
function gerarForm($qtd_campos, $qtd_maxima){
//Se $qtd_campos receber um número de ponto flutuante, intval() irá retornar a parte iteira desse número.
$qtd_campos = intval($qtd_campos);
//A variável $qtd_campos precisa ter um valor menor que a quantidade máxima permita e não deve ser um número negativo.
if(!($qtd_campos > $qtd_maxima || $qtd_campos < 0)){
echo '<form name="form" enctype="multipart/form-data" method="post" action="upload.php">';
//A iteração é feita começando com o valor 1 para evitar a sáida "Imagem: 0".
for($linha = 1; $linha < = $qtd_campos; $linha++){
echo
'<label>
<span>Imagem: '.$linha.'</span>
<input type="file" name="arquivo[]" />
</label>';
}
echo
'<input name="enviar" type="submit" value="Realizar Upload" />
</form>';
}else{
echo 'É preciso inserir um valor válido!
<a href="javascript:history.go(-1)">Voltar</a>
';
}
}
O segredo do upload múltiplo esta nessa linha:
<input type="file" name="arquivo[]" />
Quando se deseja enviar várias imagens é preciso definir o atributo name do input como um array, assim a super global $_FILES se comportará de maneira diferente de quando é enviado uma imagem apenas.
Agora nosso upload esta 95% concluído, precisamos apenas enviar as imagens para uma pasta rsrs…
Com as imagens inseridas nos campos da página form_upload.php estamos prontos para submeter o formulário e o script upload.php irá realizar todo o upload.
//Inclui o arquivo contendo as duas funções da aplicação.
require('funcoes.php');
//Verifica se FILES foi enviado por HTTP.
if(isset($_FILES)){
//Essa função recebe apenas um parâmetro, um array contendo as informações das imagens enviadas.
echo uploadMultiplo($_FILES['arquivo']);
}else{
echo 'O formulário não foi preenchido corretamente!
<a href="javascript:history.go(-1)">Voltar</a>
';
}
Vejam que ele é muito parecido com form_upload.php. A função uploadMultiplo() também esta localizada no arquivo funções.php e recebe apenas um parâmetro, o array $_FILES[‘arquivo’] onde se encontra todas as informações necessárias para o upload das imagens.
Quando fazemos um upload simples, com uma única imagem obtemos um array com cada índice contendo os valores padrões de $_FILES: [name], [type], [tmp_name], [error] e . Estrutura do array obtido:
Array
(
[arquivo] => Array
(
[name] => imagem.jpg //Nome da imagem.
[type] => image/jpeg //Tipo mime da imagem.
[tmp_name] => C:\wamp\tmp\phpB1B.tmp //Nome temporário no servidor.
[error] => 0 //Código de erro.
[size] => 00000 //Tamanho em bytes.
)
)
Mas quando fazemos um upload múltiplo o array fica ligeiramente diferente… Supondo que duas imagens são enviadas o array ficaria assim:
Array
(
[arquivo] => Array
(
[name] => Array
(
[0] => imagem.jpg
[1] => imagem.jpg
)
[type] => Array
(
[0] => image/jpeg
[1] => image/jpeg
)
[tmp_name] => Array
(
[0] => C:\wamp\tmp\php944.tmp
[1] => C:\wamp\tmp\php945.tmp
)
[error] => Array
(
[0] => 0
[1] => 0
)
[size] => Array
(
[0] => 00000
[1] => 00000
)
)
)
Viram a diferença? Agora temos um array onde cada índice é um novo array e as informações das imagens são os valores dos índices desse array.
Entendendo como funciona a estrutura do upload, podemos analisar a função uploadMultiplo().
function uploadMultiplo($arquivo){
//Diretório onde as imagens serão armazenadas.
$diretorio = 'imagens/';
//Essas variáveis serviram para a contagem de upload das imagens que apresentarem erros ou não.
$com_erro = $sem_erro = 0;
//Formatos de imagens suportados.
$formatos = array('jpg','png','gif','bmp');
//Iterando o array $arquivo podemos acessar cada imagem enviada pelo formulário da página anterior.
for($linha = 0; $linha < count($arquivo['tmp_name']); $linha++){
//A função in_array verifica se um valor existe no array passado como parâmetro. A extensão da imagem é capturada com a função substr() depois testamos se ela esta presente no array $formatos.
if(in_array(substr($arquivo['name'][$linha], -3), $formatos)){
//Se tudo ocorrer bem, o upload será realizado com sucesso e a imagem será enviada para a pasta configurada em $diretorio.
if(!(move_uploaded_file($arquivo['tmp_name'][$linha], $diretorio.$arquivo['name'][$linha]))){
//Caso um erro aconteça a variável $com_erro é incrementada em uma unidade.
$com_erro++;
}else{
//Caso nenhum erro ocorra, a variável $sem_erro é incrementada em uma unidade.
$sem_erro++;
}
}else{
$com_erro++;
}
}
//Retornamos uma mensagem que informa o número de imagens que apresentaram erros e as que não tiveram erro algum após a execução do upload.
$aviso = 'Uploads realizados com sucesso: '.$sem_erro.'<br />Uploads que apresentaram falhas: '.$com_erro;
return $aviso;
}
Para que as imagens possam ser salvas no diretório ‘imagens/’ precisamos verificar se ela tem um formato válido. Usei a função in_array() em combinação com substr() para mostrar uma outra alternativa possível, mas o indicado seria utilizar uma expressão regular com a função preg_match() dessa maneira:
preg_match("/^image\/(pjpeg|jpeg|png|gif)$/", $arquivo['name'][$linha]);
Com uma iteração podemos percorrer os índices de $arquivo facilmente e com isso realizar o upload de cada imagem.
Para que não seja uma iteração infinita coloquei um limite utilizando a função count($arquivo['tmp_name']) para obter o total de imagens enviadas. Também seria possível utilizar qualquer outro índice como [‘name’] ou [‘size’] pois todos possuem a mesma quantidade de elementos dentro do array.
O interessante de se fazer um sistema de upload desses é que não importa a quantidade de imagens que se deseja enviar, pode ser apenas 1 ou 100 e o limite é você quem define.
E para finalizar a função, uma mensagem informando o número de arquivos que foram enviados com sucesso e os que apresentaram falhas é retornada.
Como é possível perceber não realizei nenhuma validação significativa, em um sistema final é muito importante realizar verificações mais consistentes. Esse assunto abrange bastante coisa interessante como: redimensionar as imagens criando thumbnails, enviar imagens para pastas específicas, definir nomes aleatórios evitando que sejam sobrescritas e muitas coisas mais… Meu foco foi apenas mostrar como funciona um upload múltiplo! :P
Qualquer dúvida, elogio ou errata é só deixar um comentário ou mandar um twitte para @leonardo_tm que irei responder com prazer ;)
Discussão (0)
Carregando comentários...