Dev (Back & Front)ARTIGO

Construindo uma enquete usando Flex e PHP

Olá, desbravadores! Veremos hoje um tema bem interessante, o uso de flex com alguma tecnologia server-side. Neste exemplo usarei PHP, mas nada impede que seja usada outra tecnologia como ASP, JSP ou outra.

Para ilustrar, iremos construir uma enquete onde o usuário poderá votar e ver o resultado dos votos.

Vamos aos conceitos. Há varias maneiras de fornecer dados para que o flex possa exibir e/ou manipular essas informações para os usuários. Se você usa PHP, pode fazer isso com zendAmf ou com AmfPHP, se usa Java, pode usar o BlazeDs. Enfim, existem diversas formas e, nesse caso, iremos usar um componente do flex que nos permite enviar e receber dados de um arquivo no servidor.

O componente é o HTTPService, que permite acessar um arquivo no servidor. Poderíamos usar RemoteObject usando zendAmf ou AmfPHP, que é mais rápido. Porém, para esse caso em que trabalhamos com um número pequeno de dados vindo do servidor, usar HTTPService resolverá nosso problema facilmente, sem comprometer o desempenho.

Atente para os seguintes detalhes, que são muito importantes.

  1. O atributo url deste componente seta o arquivo que será acessado pelo flex;
  2. O atributo result define que método será chamado quando a requisição for finalizada;
  3. O atributo fault define que método será chamado quando a requisição falhar.
  4. Para executar a requisição, é preciso usar o método send().

Imaginemos o seguinte cenário:

Você tem uma aplicação feita em flex com o nome teste.mxml. Ao compilar esse arquivo, será gerado um arquivo com o nome teste.swf. Essa aplicação precisa receber um dado do arquivo teste.php, que está no mesmo diretório do teste.swf. Para que isso ocorra, colocamos o seguinte trecho de código na nossa aplicação flex (teste.mxml):

<mx:HTTPService id="dataRequest" url="teste.php" result="RequestResult (event);" fault="FaultHandler(event);" />

Trecho do código PHP:

echo "Dados enviado pelo PHP";

Veja na figura abaixo o comportamento dessa transação:

Ao clicar no botão, o resultado é um alerta com a mensagem “Dado enviado pelo PHP”.

E se for necessário enviar dados do flex para o php? Bom, nesse caso iremos implementar nosso código criando um método chamado enviaDado(). Nesse método usaremos o URLVariables, que nos permitirá passar os dados do flex para o lado php. Além disso, iremos utilizar o atributo method no HTTPService, definindo que os dados serão enviados para o PHP pelo método POST. Confira o novo comportamento abaixo:

O resultado é um alerta com a mensagem “Dado enviado pelo PHP com Dado do flex”. Repare que criei o objeto URLVariables e “criei as variáveis” que serão enviadas ao servidor utilizando o comando obj.Variavel = valor;. Se tiver que enviar mais informações, basta repetir esse código, mudando apenas o nome da variável e o valor.

Depois de toda essa teoria, vamos à prática. Nosso exemplo consiste em criar um aplicativo (uma enquete) que permita aos usuários votarem em opções que serão dadas e depois conferirem o resultado da enquete. Confira o fluxo da aplicação:

Fluxo – Enquete (Flex+PHP)

  1. Sistema – Buscar dados do servidor;
  2. Sistema – Montar a estrutura da enquete;
  3. Usuário – Escolher uma opção;
  4. Sistema – Exibir Alerta pedindo confirmação do voto;
  5. Usuário – Confirmar a opção escolhida;
  6. Sistema – Enviar dados para o servidor;
  7. Sistema – Confirma o voto;
  8. Sistema – Fechar o Panel da Enquete;
  9. Sistema – Abrir o Panel dos resultados;
  10. Sistema – Busca dados sobre os resultados da enquete;
  11. Sistema – Anima o gráfico;
  12. Usuário – Clica em votar novamente;
  13. Sistema – Volta ao passo 3.

Fluxo Alternativo – Enquete (Flex+PHP)

1.1   Sistema – Caso não consiga buscar os dados, exibe a falha e encerra.
5.1   Usuário – Caso não confirme a escolha, o sistema confirma que não houve escolha e volta ao passo 3.
6.1   Sistema – Caso não consiga buscar os dados, exibe a falha e encerra.

Confira o gráfico que ilustra o relacionamento dos arquivos:

Explicação de cada arquivo:

  • FlexEnquete.mxml = Arquivo fonte com o código flex.
  • FlexEnquete.swf = Arquivo gerado a partir do FlexEnquete.mxml – esse é o arquivo que o usuário acessa e que faz a comunicação com o php.
  • cfg.php = Arquivo responsável pela conexão com banco de dados.
  • enquete.php = Arquivo que gera os dados da enquete.
  • resultados.php = Arquivo que gera os dados com os resultados da enquete.
  • voto.php = Arquivo que computa os votos.

O código está todo comentado, mas vamos a alguns detalhes relevantes:

Primeiro, atentemos para os três componentes HTTPService: cada um aponta para um arquivo php, que são os responsáveis pelas transações com o banco de dados. Todos eles (HTTPService) apontam para o evento requestFaultHandler, caso algum problema aconteça com a requisição ao PHP.

O primeiro HTTPService a ser chamado é o dataRequest, ele é responsável por trazer os dados da enquete. Se tudo ocorrer bem na requisição, será evocado o método enqueteRequestResultHandler, que tratará os retorno e irá gerar a tela da enquete.

No caso de o usuário escolher uma opção, o HTTPService que será chamado será o votoRequest, que enviará os dados e retornará a resposta para o método votoRequestResultHandler, que, por usa vez, avisará o resultado ao usuário, limpará as informações referentes à opção escolhida, fechará a tela da enquete, abrirá a tela que mostrará os resultados e chamará o método send() do HTTPService enqueteRequest, que fará uma requisição ao arquivo resultado.php. No retorno, será chamado o método enqueteRequestResultHandler, que tratará os dos dados referente ao resultado da enquente.

Outro ponto muito importante foi não deixar a enquete engessada, ou seja, a quantidade de opções de cada enquete não irá influenciar no comportamento dela. Assim, em determinado momento, poderemos definir que a enquete tenha apenas duas opções e, em outro momento, poderá ter quatro opções, e nada mudará no código.

Como fazer isso? Simples: o arquivo enquete.php informa quantas opções existem para aquela enquete, no método enqueteRequestResultHandler fazemos um for, que verifica a quantidade de opções (dados.length) e fará as iterações inserindo um HBox um Label e um RadioButton para cada opção da enquete. Desse modo, garantimos que haverá a quantidade de opções que quisermos, deixando nossa aplicação Flex mais flex 😉

Por último, destaco também o comando rb.addEventListener(MouseEvent.CLICK,rbClick). Esse comando irá criar escutas para cada RadioButton. Assim, se algum desses RadioButton forem clicados, conseguiremos saber qual e poderemos capturar informações referentes à opção clicada. O método rbClick() será chamado e receberá um argumento do tipo MouseEvent. Usando o comando evt.target.id, poderemos saber que RadioButton foi clicado. Detalhe: cada RadioButton da enquete recebe em seu id o código da opção da enquete à qual se refere. Executando o comando evt.target.value, podemos pegar o valor do RadioButton. Nesse caso, defini que seria o titulo da opção.

Em relação aos arquivos php, não irei explicá-los, uma vez que o objetivo deste artigo é o flex, mas neles não tem nada demais, apenas que dois deles geram XML e um não. Qual será o que não gera, hein?

Confira abaixo a as telas da enquete, logo após um link para vê-la em ação, um para baixar o código fonte completo (inclusive com banco de dados) e, por último, confira o código fonte totalmente comentado.

Veja o aplicativo em ação: http://www.aprendaweb.com.br/flex/FlexEnquete/

Baixe o aplicativo completo com o código fonte+PHP+BD: http://www.easy-share.com/1910024777/FlexEnqueteAprendaWeb.rar

Confira o código todo comentado

<?xml version="1.0" encoding="utf-8"?><br /><mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"<br />	creationComplete="ini();" width="500" height="400" backgroundColor="#ffffff" backgroundGradientColors="#ffffff"><br />	<mx:Script><br />		<![CDATA[<br />			//Importamos os controles que serão usados na aplicação<br />			import mx.controls.RadioButton;<br />			import mx.controls.CheckBox;<br />			import mx.controls.Label;<br />			import mx.containers.HBox;<br />			import mx.controls.*;<br /><br />			//Importamos os eventos<br />			import mx.events.CloseEvent;<br />			import mx.rpc.events.FaultEvent;<br />			import mx.rpc.events.ResultEvent;<br /><br />			//Tambem usaremos o ArrayCollection para gerar a enquente<br />			import mx.collections.ArrayCollection;<br /><br />			//Array que guardará as opções<br />			public var dados:ArrayCollection;<br /><br />			//Array que guardará os dados da enquete<br />			public var enquete:ArrayCollection;<br /><br />			//Variável do tipo XMLList que será usado para gerar o gráfico de resultados<br />			[Bindable]<br />			public var resultados:XMLList;<br /><br />			//Método inicial <br />			private function ini():void{<br />				//inciamos a chamada para colher as informações sobre a enquete<br />				dataRequest.send();<br />			}<br /><br />			//Método que é chamado quando os dados da enquente são colhidos no PHP<br />			public function dataRequestResultHandler(event:ResultEvent):void {<br />				//Pegamos todos os nós 'opcao' no xml Gerado pelo PHP<br />			    dados = event.result.data.opcao;<br /><br />			    //Pegamos todos os nós 'enquete' no xml Gerado pelo PHP<br />			    enquete = event.result.data.enquete;<br /><br />			    //Colocamos a pergunta no Label com id pergunta<br />				pergunta.text = enquete[0]["titulo"];<br /><br />			    //Fazemos um for para inserir todas as opções da enquete<br />			    for(var n:int = 0; n < dados.length; n++){<br />			    	//Para cada iteração do for inserimos um HBox<br />					var h:HBox = new HBox();<br />					//Adcionamos o HBox criado no Canvas com id 'op'<br />					op.addChild(h);<br />					//Para cada iteração do for inserimos um Label<br />					var l:Label = new Label();<br />					//Colocamos o titulo da opçãoo da enquente como texto do Label<br />					l.text = dados[n]["titulo"];<br />					//Definimos o tamnho do Label<br />					l.width = 400;<br />					//Adcionamos o Label dentro do HBox que acabamos de criar <br />					h.addChild(l);<br />					//Para cada iteração do for inserimos um RadioButton<br />					var rb:RadioButton = new RadioButton();<br />					/*<br />					Aqui vai uma parte importante: adicionamos uma 'escuta' que vai<br />					ficar observando se algum dos RadioButtons foi clicado, caso algum<br />					seja clicado o método rbClick é acionado<br />					*/<br />					rb.addEventListener(MouseEvent.CLICK,rbClick);<br />					/*<br />					Definimos um valor para o RadioButton neste caso o titulo da opcao<br />					da enquete.<br />					*/<br />					rb.value = dados[n]["titulo"];<br />					//Definimos o id do RadioButton que será o mesmo id da opção da enquete<br />					rb.id = dados[n]["id"];<br />					//Adcionamos o RadioButton dentro do HBox Criado<br />					h.addChild(rb);<br /><br />					/*<br />					O for irá se repitir de acordo com a quantidade de opções que a enquete<br />					oferece, garantindo que haja tantos elementos quantos nescessário. Caso<br />					uma enquente só tenha duas opções o for irá se repitir 2 vezes<br />					e inserir duas opções, se for quatro opções irá se repitir 4 vezes e assim<br />					por diante, dando assim a essa enquente flex ;)<br />					*/<br />				}<br />			}<br /><br />			//Método que é acionado quando um RadioButton é clicado<br />			private function rbClick(evt:MouseEvent):void {<br />				//Exibimos um alerta para o usuário confirmar seu voto. <br />                Alert.show("Você escolheu a opção: "+ evt.target.value +"\n Deseja confirmar?","Atenção",3,this, <br />                function(event:CloseEvent):void{<br />                	//Se o usuário escolher sim<br />                	if(event.detail == Alert.YES){<br />                		//dismarcamos o RadioButton<br />						evt.target.selected = false;<br />						//criamos um objeto para passar os dados para o PHP<br />						var obj:URLVariables = new URLVariables();<br />						//passamos o id da opção<br />						obj.opCodigo = evt.target.id;<br />						//passamos o valor(titulo) da opção<br />						obj.opTitulo = evt.target.value;<br />						//enviamos os dados para o código PHP definido no HTTPService<br />						votoRequest.send(obj);<br />					}else{<br />						/*<br />						se o usuário clicar em não na confirmação do voto, dismarcamos<br />						a opção escolhida e exibimos uma mensagem avisando que o usuário<br />						ainda não realizou seu voto.<br />						*/ <br />						evt.target.selected = false;<br />						resultVoto.text = "Atençao você ainda não votou! Escolha uma opção.";<br />				 	}<br />                });<br />            }<br /><br />            //Métado que é chamdo quando qualquer erro de chamada aos arquivos PHP falham<br />			private function requestFaultHandler(event:FaultEvent):void {<br />			    Alert.show(event.fault.message);<br />			}<br /><br />			//Método que é chamado na resposta do envio do voto<br />			private function votoRequestResultHandler(event:ResultEvent):void{<br />				//Exibimos um Alerta com o texto que vem do PHP<br />				Alert.show(event.result.toString(),"Atenção!",0,null,function():void{<br />					//'Fechamos' a tela da enquete<br />					pnlEnquete.visible = false;<br />					//'Abrimos' a tela do resultado da enquete<br />					pnlResultado.visible = true;<br /><br />					/*<br />					Enviamos dados para realizar a consulta que irá gerar o resultado<br />					da enquete<br />					*/<br />					var obj:URLVariables = new URLVariables();<br />					obj.enqCodigo = enquete[0]["id"];<br />					enqueteRequest.send(obj);<br />				});<br />			}<br /><br />			/*<br />			Método que é chamdo na resposta do envio dos dados para realizar a consulta <br />			que gera os dados para o gráfico <br />			*/<br />			public function enqueteRequestResultHandler(event:ResultEvent):void {<br />				//colhemos os dados para o gráfico<br />				resultados = event.result.opcao;<br />			}<br /><br />			//Método para permitir o usuário votar novamente<br />			private function votarDeNovo():void{<br />				//'Abrimos' a tela da enquete<br />				pnlEnquete.visible = true;<br />				//'Fechamos' a tela do resultado da enquete<br />				pnlResultado.visible = false;<br />			}<br />		]]><br />	</mx:Script><br />	<!--Componente para se comunicar com o arquivo enquete.php--><br />	<mx:HTTPService id="dataRequest" url="enquete.php" <br />		result="dataRequestResultHandler(event);" fault="requestFaultHandler(event);" /><br /><br />	<!--Componente para se comunicar com o arquivo resultados.php-->	<br />	<mx:HTTPService id="enqueteRequest" url="resultados.php" method="POST"<br />		result="enqueteRequestResultHandler(event);" fault="requestFaultHandler(event);" resultFormat="e4x"/><br /><br />	<!--Componente para se comunicar com o arquivo voto.php--><br />	<mx:HTTPService id="votoRequest" url="voto.php"<br />	result="votoRequestResultHandler(event)" fault="requestFaultHandler(event)" method="POST"/><br /><br />	<!--Componente que gerá o efeito no gráfico dos resultados--><br />	<mx:SeriesSlide id="slideIn" duration="3000" direction="right" /><br /><br />	<!--Painel da enquete--><br />	<mx:Panel id="pnlEnquete" title="Enquete" paddingLeft="10" paddingTop="10" width="480" top="10" left="10"><br />		<!--Label que irá conter a pergunta --><br />		<mx:Label id="pergunta" fontWeight="bold" /><br />		<!--Tela que irá conter as opções--><br />		<mx:VBox id="op" /><br />		<!--Label que exibirá mensagens--><br />		<mx:Label id="resultVoto" fontWeight="bold" /><br />	</mx:Panel><br /><br />	<!--Painel do gráfico com os resultados--><br />	<mx:Panel id="pnlResultado" title="Resultado" paddingLeft="10" paddingTop="10" width="480" <br />		visible="false" top="10" left="10"><br />		<!--Definimos o dataProvider com a variavel resultados que contém os dados vindos do banco--><br />		<mx:BarChart id="Chart" height="200" color="0x323232" showDataTips="true" dataProvider="{resultados}"><br />			<!--Exibiremos as opções como legenda no eixo y--><br />	 		<mx:verticalAxis><br />				<mx:CategoryAxis categoryField="titulo"/><br />			</mx:verticalAxis><br />			<mx:series><br />				<!--chamaremos o efeito slideIn--><br />				<!--Os daos do eixo y será os titulos--><br />				<!--Os dados do eixo x será os votos--><br />				<mx:BarSeries id="bar" showDataEffect="{slideIn}" yField="titulo" xField="votos" displayName="Votos"/><br />			</mx:series><br />    	</mx:BarChart><br />        <mx:HBox><br />	        <mx:Legend dataProvider="{Chart}"/><br />	        <mx:Button label="Votar novamente!" click="votarDeNovo();" />	<br />        </mx:HBox><br />	</mx:Panel><br /></mx:Application>

Espero que tenham gostado! No próximo artigo, pretendo mostrar como formatar essa enquete para deixá-la com um layout muito legal. Até a próxima.

é estudante do curso de Desenvolvimento de Sistema para Internet da FATEC-JP. Atuante na área de desenvolvimento web há cinco anos, com conhecimentos avançados em ASP, PHP, XHTML, CSS, JavaScript, Ajax e ferramentas gráficas como Photoshop e Corel Draw. Há um ano estuda Flex e o utiliza em projetos na empresa que trabalha.

Ver perfil

Mais de José Benito F. da Silva