Havia muita gente que quebrava a cabeça até um tempo atrás, para criar formulários de upload. Sejam unitários ou múltiplos.
Criavam-se dezenas de linhas, para uma tarefa que o pacote HTTP_Upload do PEAR, realiza em pouquíssimas!
A tarefa, como veremos a seguir, é extremamente simples. Tanto que vamos criar o formulário e fazer o upload de 5 arquivo, em um único script.
Caso você tenha acesso à linha de comando da máquina, digite apenas "install pear HTTP_Upload". Caso não tenha, baixe o pacote HTTP_Upload do site do PEAR e coloque dentro da pasta do mesmo, fazendo a chamada para a classe Upload.php diretamente, como faremos neste artigo.
A primeira parte vai ser criar o formulário, como abaixo: (note que no meu exemplo, há também um local para onde os arquivos irão após o upload. Isso é de fácil personalização, você pode guardar em vários locais, arquivos que subiram por este formulário)
PHP
<!-- formulário simples para o envio de 5 arquivos simultâneos -->
<form action="<?php echo $_SERVER['PHP_SELF'];?>?enviaform=1" method="post" enctype="multipart/form-data">
Selecione os arquivos:<br>
<input type="hidden" name="MAX_FILE_SIZE" value="100000"><BR>
<input name="userfile[]" type="file"> <-<br>
<input name="userfile[]" type="file"><br>
<input name="userfile[]" type="file"><br>
<input name="userfile[]" type="file"><br>
<input name="userfile[]" type="file">
<br>
<br>
Destino dos arquivos:
<input name="destino" type="text" id="destino">
( para mesma pasta, digite ./ ) <br>
<br>
<input type="submit" value="Enviar arquivos">
</form>
<!-- fim do formulário -->
</body></html>
Note o seguinte:
- No action do form, estou chamando a mesma página, via GET, e passando como ação, o valor enviaform. Isso significa que, ao enviar o formulário para a mesma página e ele encontrar a ação enviaform, irá efetuar as ações de script que veremos a seguir.
- Os inputs do form, tem os mesmos nomes, que serão as arrays lidas pelo foreach do script, afim de efetuar as ações de upload dos arquivos presentes dentro de cada input.
Á seguir, o começo do script, onde vamos recuperar a ação enviaform. Se a ação estiver setada (isset), continua, caso contrário, sai do script (exit).
PHP
<?php
if(!
isset($_GET['enviaform'])) { }
O próximo passo, é realizar a chamada ao pacote HHTP_PEAR, como abaixo:
PHP
// local da classe
require_once('../PEAR/HTTP_Upload/Upload.php');
Note que, estou fazendo a chamada ao arquivo da classe, diretamente, visto que não tenho acesso ao SSH da máquina na qual desenvolvi a aplicação.
Dando continuidade, resgatando o local de destino dos arquivos, e instanciando a classe de upload:
PHP
$destino = $_POST['destino'];
$upload = new http_upload('en');
O processo de recuperar a quantidade de inputs do tipo "file" do formulário é simples. Primeiro, a função getFiles da classe irá recuperar a quantidade de inputs (por isso você pode colocar quantos quiser) e após, será feito o foreach para ler estes inputs:
PHP
$files = $upload->getFiles();
foreach($files as $file){
if (PEAR::isError($file)) {
die ($file->
getMessage());
}
Como você viu acima, recuperei através do método $upload, todos os arquivos (getFiles) presentes no form. Agora vamos verificar se algum campo estava vazio, assim ele irá subir apenas campos com arquivos, ao invés de dar erro de campo vazio.
PHP
if ($file->isValid()) {
$file->setName('uniq');
$dest_dir = $destino;
$dest_name = $file->moveTo($dest_dir);
if (PEAR::isError($dest_name)) {
die ($dest_name->
getMessage());
}
Entendendo um pouco mais sobre o que foi feito acima:
- Para não correr o risco de sobrescrever outro arquivo presente anteriormente no diretório, vamos manter nomes dinâmicos e randômicos. Então, após recuperar os arquivos do tipo "file", a linha 2, contém a função setName, que será responsável por realizar a troca dos nomes dos arquivos presentes em cada input.
- A linha 3, indica para que local irão os arquivos que estão sendo enviados através do formulário.
- A linha 4, seria um aquivalente ao move_uploaded_file do php, movendo o arquivo já renomeado, para o local correto.
- As linhas 5,6 e 7, são a verificação de erro. Se alguma ação não puder ser realizada, será retornada uma mensagem de erro.
Prosseguindo, vou fazer uma apresentação do que aconteceu durante o período de upload do arquivo. Pegando o nome real, exibindo-o e mostrando novo nome dado ao mesmo, bem como a pasta para onde foi enviado:
PHP
$real = $file->getProp('real');
echo "Upload do arquivo $real feito com sucesso. Foi renomeado para $dest_name
e está agora localizado na pasta $dest_dir <BR><BR>";
Caso a função getFiles não encontrar nenhum dos campos de input preenchidos, retornará um erro:
PHP
} elseif ($file->isMissing()) {
echo "Nenhum arquivo selecionado<BR>";
E finalizando, caso os arquivos sejam do tamanho válido, e não contenham nenhum erro, seja nos próprios arquivos, seja na permissão de pastas do servidor, etc, retorna erro.
PHP
} elseif ($file->isError()) {
echo $file->
errorMsg() .
"\n";
}
}
Se você utiliza o GMAIL, deve estar acostumado a ver, que ao anexar um arquivo, você pode adicionar outro, adicionando inputs à tela de envio do email. Você pode criar uma função como essa (que é feita em javascript) e criar os seus inputs mais dinâmicos ainda, utilizando esta fantástica classe para realizar o envio dos mesmos.
Dúvidas, comente aqui ou envie um email.