Boa noite pessoal!

Recentemente estava desenvolvendo uma galeria de imagens e me deparei com um problema: Como possiblitar que o usuário selecione vários arquivos de uma só vez? Como não gostaria de simplesmente inserir vários campos “file” (o que faria o usuário selecionar 1 por 1), eu poderia comprar um Applet Java ou procurar por componentes prontos. Mas como as últimas versões do Flash possibilitam a seleção múltipla de arquivos, decidi pesquisar sobre isso e criar minha própria sistemática alá álbum de fotos do Orkut.

1. Para iniciar, crie um novo Documento Flash e adicione o texto “Adicionar”, pois a partir do Flash Player 10 a função de seleção de arquivos só pode ser chamada de dentro do swf, por segurança.

2. Acesse o painel de Actions e adicione o seguinte código:

// Objeto que possibilita seleção múltipla dos arquivos
var fileRefList:FileReferenceList = new FileReferenceList();
 
// Guarda o "id" arquivo que está sendo enviado no momento
var atual:Number = 0;
 
// Array dos arquivos selecionados
var selecionados:Array;
 
// Evento CLICK no stage para seleção dos arquivos
stage.addEventListener(MouseEvent.CLICK, clique);
 
// Abre janela de seleção dos arquivos
function clique(e:MouseEvent):void
{
	fileRefList.browse();
}

Este código já é suficiente para fazer o flash exibir a janela para seleção múltipla de arquivos. O próximo passo agora será o envio dos arquivos, um log básico para que usa o Firebug e notificar a página quando um arquivo é enviado.

// Evento ao selecionar os arquivos e clicar em "Abrir"
fileRefList.addEventListener(Event.SELECT, selectHandler);
 
function selectHandler(e:Event):void
{
	// Retorna os arquivos selecionados
	var arqs:FileReferenceList = FileReferenceList(e.target);
 
	// Seta a array com os arquivos selecionados
	selecionados = arqs.fileList;
 
	// Envia o primeiro arquivo da array
	enviar(0);
}
 
function enviar(i:Number):void
{
	// URL do script php para o upload
	var url:URLRequest = new URLRequest("http://localhost/upload.php");
 
	// Arquivo a ser enviado
	var arq:FileReference = FileReference(selecionados[i]);
 
	// Evento que dispara quando o Flash recebe um retorno do script php
	arq.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA, completeHandler);
	// Evento que dispara quando ocorre um erro de entrada/saída
	arq.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
 
	try {
		// Envia o arquivo
		arq.upload(url);
	} catch (erro:Error) {
		log("Ocorreu um erro ao enviar o arquivo "+arq.name);
	}
}
 
// Executa ao completar o envio e receber um retorno do script php
function completeHandler(e:DataEvent):void
{
	// Seta a variavel com a referencia do arquivo enviado
	var arq:FileReference = FileReference(e.target);
 
	// Executa a função javascript "enviado" da página e envia o nome do arquivo
	ExternalInterface.call("enviado", arq.name);
 
	log(arq.name+" enviado.");
 
	// Remove os eventos
	arq.removeEventListener(DataEvent.UPLOAD_COMPLETE_DATA, completeHandler);
	arq.removeEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
 
	// Incrementa o indice para enviar o próximo arquivo
	atual++;
 
	// Verifica se todos os arquivos foram enviados
	if (atual < selecionados.length)
		enviar(atual);
	else
		log("Todos os arquivos foram enviados.");
}
 
function ioErrorHandler(e:IOErrorEvent):void
{
	// Seta a variável com o arquivo da tentativa de envio
	var arq:FileReference = FileReference(e.target);
 
	log("Ocorreu um erro de entrada/saída no arquivo " + arq.name);
}
 
// Loga mensagens com trace e console.log (Firebug)
function log(msg:String):void
{
	trace(msg);
	ExternalInterface.call("console.log", msg);
}

Obs.: Não esqueça de alterar a URL do seu script de upload.

O código PHP pode ser bem simples, como o seguinte:

// Por padrão, o Flash envia o arquivo como 'Filedata'
$file = $_FILES['Filedata'];
 
// Onde salvar o arquivo
$arquivo = "uploads/".$file['name'];
 
// Move o arquivo e retorna o resultado para o Flash com o "echo"
echo move_uploaded_file($file['tmp_name'], $arquivo);

É importante lembrar que dependendo do seu servidor será necessário permissão de escrita no diretório “uploads”.

E por fim você deve fazer uma página com o swf, uma div com id=”arquivos” e a função Javascript “enviado()” para receber o nome do arquivo que foi enviado com sucesso ao servidor. Abaixo o código Javascript que coloquei na tag head da página:

// O Flash executa esta função quando o arquivo termina de ser enviado
function enviado(nome)
{
	// Insere a mensagem na div #arquivos
	document.getElementById("arquivos").innerHTML += '<div>'+nome+' enviado.</div>';
}

Código HTML (body):

<object width="100" height="30" type="application/x-shockwave-flash" id="uploader" name="uploader" data="upload.swf">
	<param name="menu" value="false"/>
	<param name="allowScriptAccess" value="always"/>
</object>
 
<div id="arquivos"></div>

Faça o download dos arquivos:

http://fredimachado.com.br/wp-content/plugins/downloads-manager/img/icons/winrar.gif download: upload.rar (8.54KB)
added: 30/04/2009
clicks: 647
description: Arquivos utilizados neste post.

Em breve vou postar uma versão bastante melhorada, integrando jQuery e barra de progresso.

Um abraço e até a próxima!