Motivação
É bem sabido na comunidade de desenvolvedores a importância de disponibilizar os recursos de download e upload de arquivos de forma fácil e intuitiva. Nesse quesito, diversos são os frameworks que visam simplificar nossa vida, abstraindo boa parte da implementação de código HTML, JavaScript e CSS que teríamos de escrever para criar recursos mais robustos e completos. Entretanto, a maioria deles falha no quesito usabilidade quando, por exemplo, não viabiliza funções de “arrastar e soltar”, status do upload (como barras de progresso), sistemas de feedback com mensagens de validação/erro/sucesso, dentre outras.
Este artigo visa expor rapidamente os benefícios que tais frameworks nos trazem através da construção de uma mini aplicação que faz o upload de imagens para um diretório qualquer, usando o framework JavaScript DropzoneJS em conjunto com o PHP como linguagem de servidor.
Passo 1: Instalando o DropzoneJS
O DropzoneJS é uma biblioteca open source que implementa o recurso de upload de arquivos via drag and drop. Ela é leve, não depende de outras bibliotecas JavaScript e, ao lidar com arquivos de imagens, ainda fornece a opção de pré-visualizar as mesmas.
Para efetuar a sua instalação, baixe os arquivos JavaScript e CSS do DropzoneJS no GitHub e importe-os na página HTML através do seguinte código:
<link rel="stylesheet" href="dropzone.css" />
<script src="dropzone.js"></script>
Para fins de padronização e performance, opte por carregar seus arquivos CSS dentro do cabeçalho HTML, e os arquivos JavaScript após o corpo da página.
Quando esse código for executado no navegador, teremos o DropzoneJS importado e acessível via objeto JavaScript window.Dropzone, bem como disponibilizados os estilos que acompanham o framework.
Passo 2: Criando a classe dropzone
Nosso próximo passo é a criação do elemento de formulário que lidará com a seleção e envio dos arquivos. Nele, adicionaremos a classe dropzone que incutirá o estilo característico do framework:
<form action="upload.php" class="dropzone" id="meuPrimeiroDropzone">
</form>
Além do estilo, essa classe também permite que o DropzoneJS inicialize todos os seus eventos de upload e os atrele ao respectivo formulário. Assim, quando efetuarmos um submit no form, todos os arquivos selecionados serão enviados via request para o endereço registrado no atributo action.
Você também pode ter o mecanismo de upload de arquivos sem o uso de JavaScript, utilizando o processo de fallback. Para isso, precisamos incluir a classe fallback no HTML, de preferência em uma div interna, a qual o DropzoneJS remove quando a página é carregada no navegador. Vejamos como criá-la na Listagem 1.
1 <form action="upload.php" class="dropzone" id="meuPrimeiroDropzone">
2 <div class="fallback">
3 <input name="fileToUpload" type="file" multiple />
4 </div>
5 </form>
Passo 3: Usando o DropzoneJS programaticamente
Uma opção à importação do DropzoneJS via tag <script> é habilitá-lo programaticamente, instanciando a classe dropzone no JavaScript, conforme o código:
var
meuDropzone = new Dropzone("div#meuId", {url:
"upload.php"});
O nível de integração do DropzoneJS se estende, inclusive, a outros frameworks JavaScript mais comuns, como é o caso do jQuery. Para habilitá-lo com os seletores jQuery, basta usar o seguinte código:
$("div#meuId").dropzone({ url: "upload.php" });
A propriedade url, conforme observado, se torna obrigatória no modelo programático, uma vez que não temos uma tag de formulário com o atributo action especificado para determinar o destino dos arquivos selecionados.
Passo 4: Configurando o upload de arquivos
Uma outra maneira de configurar o upload de arquivos programaticamente é setando a propriedade options do objeto Dropzone. No fim das contas, essa propriedade funciona como uma lista com os ids de todos os formulários da página que contenham a classe dropzone. Cada configuração, por sua vez, é individual e deve ser feita separadamente no caso de termos vários formulários de upload no mesmo HTML.
Vejamos como podemos fazer isso na Listagem 2.
1 Dropzone.options.meuPrimeiroDropzone = {
2 paramName: "fileToUpload",
3 dictDefaultMessage: "Arraste seus arquivos para cá!",
4 maxFilesize: 300,
5 accept: function(file, done) {
6 if (file.name == "olamundo.png") {
7 done("Arquivo não aceito.");
8 } else {
9 done();
10 }
11 }
12 }
Linha 2: informamos o valor do atributo name do elemento de input do tipo file no formulário, o qual será usado para armazenar os arquivos até que sejam, de fato, enviados ao servidor;
Linha 3: sobrescreve a mensagem padrão do elemento de upload;
Linha 4: é definido o tamanho máximo de cada arquivo em MB;
Linha 5: função que valida se o upload deve ou não ser executado. Ela é opcional, servindo apenas para validar restrições de negócio, na tela mesmo, que possam impedir o upload;
Linhas 6 a 10: forçamos um teste para verificar o mecanismo de validação do DropzoneJS. Se o arquivo selecionado tiver o nome olamundo.png, o upload será negado e a mensagem da linha 7 será exibida, caso contrário (linha 9), prosseguimos com o upload.
A Figura 1 mostra como ficará nossa página quando for executada no navegador.
Passo 5: Criando o upload PHP no servidor
Para finalizar o exemplo, precisamos implementar o código PHP que irá receber os arquivos enviados pelo DropzoneJS e salvar os mesmos em um diretório qualquer. Para isso, você precisará ter um servidor Apache instalado na sua máquina.
Dentro do servidor, na pasta onde salvamos os arquivos HTMLs (/htdocs no Xampp ou /www no WAMP), crie um novo arquivo de nome upload.php e adicione o código da Listagem 3.
1 <?php
2 // Nas versões do PHP que antecedem a versão 4.1.0, é preciso usar o $HTTP_POST_FILES em vez do $_FILES.
3
4 $uploaddir = './uploads';
5 $uploadfile = $uploaddir . basename($_FILES['fileToUpload']['name']);
6
7 echo "<pre>";
8 if (move_uploaded_file($_FILES['fileToUpload']['tmp_name'], $uploadfile)) {
9 echo "O arquivo é valido e foi carregado com sucesso.\n";
10 } else {
11 echo "Algo está errado aqui!\n";
12 }
13
14 echo "Aqui estão algumas informações de depuração para você:";
15 print_r($_FILES);
16
17 print "</pre>";
18 ?>
Linhas 4 e 5: definimos o diretório onde os arquivos serão salvos;
Linha 8: chamamos a função move_uploaded_file() do PHP. Essa função efetua o upload e retorna um booleano informando se o processo ocorreu com sucesso;
Linha 15: imprimimos todos os arquivos do diretório no log para atestar que o upload funcionou.
O restante das linhas serve apenas para logar informações adicionais que auxiliarão no debug do código.
A Figura 2 mostra o resultado final da implementação ao tentar o envio de:
- Um arquivo com sucesso;
- Um arquivo com erro (este, especificamente, cai no fluxo de exceção que implementamos, isto é, quando o nome do arquivo for olamundo.png);
- E, por fim, um arquivo de 100MB com o upload em progresso (o framework, por padrão, já vem com uma barra de loading para mostrar ao usuário o andamento do processo).