Integração do Flex com PHP através do AMFPHP

31
Integração do Flex com Integração do Flex com PHP através do AMFPHP PHP através do AMFPHP Eduardo Kraus Eduardo Kraus FloripaFlex 20/05/2009 FloripaFlex 20/05/2009

Transcript of Integração do Flex com PHP através do AMFPHP

Integração do Flex com Integração do Flex com PHP através do AMFPHPPHP através do AMFPHP

Eduardo KrausEduardo Kraus

FloripaFlex 20/05/2009FloripaFlex 20/05/2009

Quem sou eu?Quem sou eu?

• Iniciei minha vida digital aos 15 anos com Iniciei minha vida digital aos 15 anos com meu primeiro PC, um 486DX100;meu primeiro PC, um 486DX100;

• Iniciei na programação através do C++ com Iniciei na programação através do C++ com Dev-C++;Dev-C++;

• Em 2005 conheci o PHP e larguei tudo e fui Em 2005 conheci o PHP e larguei tudo e fui atrás dele;atrás dele;

• Em 2007 conheci o Flex e foi paixão a Em 2007 conheci o Flex e foi paixão a primeira vista.primeira vista.

Porque o Flex é tão bom?Porque o Flex é tão bom?

• Você programa para usuário, não para Você programa para usuário, não para browser;browser;

• Velocidade no desenvolvimento;Velocidade no desenvolvimento;• Beleza da aplicação;Beleza da aplicação;• Segurança na aplicação.Segurança na aplicação.

Integração via XMLIntegração via XML

• Maior tráfego de dados;Maior tráfego de dados;• Difícil manipulação no Flex;Difícil manipulação no Flex;• http://www.google.com/searchhttp://www.google.com/search?q=flex+?q=flex+xmlxml

publicpublic functionfunction XmlExample() { XmlExample() {

varvar employees:XML = employees:XML =

<employees><employees>

<employee ssn="123-123-1234"><employee ssn="123-123-1234">

<name first="John" last="Doe"/><name first="John" last="Doe"/>

<address><address>

<street>11 Main St.</street><street>11 Main St.</street>

<city>San Francisco</city><city>San Francisco</city>

<state>CA</state><state>CA</state>

<zip>98765</zip><zip>98765</zip>

</address></address>

</employee></employee>

</employees>;</employees>;

tracetrace(employees.employee[0].address.zip);(employees.employee[0].address.zip);

tracetrace(employees.employee[1].@ssn);(employees.employee[1].@ssn);

tracetrace(employees.employee.name);(employees.employee.name);

tracetrace(employees..zip[0]);(employees..zip[0]);

tracetrace(employees..@ssn[1]);(employees..@ssn[1]);

tracetrace(employees..name);(employees..name);

}}

Fonte: http://livedocs.adobe.com/flex/3/langref/XML.html

Integração via HTTPServiceIntegração via HTTPService

• Tráfego mais rápido que o XML;Tráfego mais rápido que o XML;• Ainda continua difícil a interpretação no Ainda continua difícil a interpretação no

Flex;Flex;• http://www.google.com/searchhttp://www.google.com/search?q=flex+?q=flex+amfamf

privateprivate varvar gateway : RemotingConnection; gateway : RemotingConnection; privateprivate functionfunction doLogin(): doLogin(): voidvoid{{ gateway = gateway = newnew

RemotingConnection(RemotingConnection("amfphp/gateway.php""amfphp/gateway.php");); gateway.call(gateway.call("classes.doLogin""classes.doLogin", , newnew

Responder(onResult, Responder(onResult, onFault),inUsuario.text,inSenha.text);onFault),inUsuario.text,inSenha.text);

}} privateprivate functionfunction onResult( result:Array) : onResult( result:Array) : voidvoid{{ Usuario.getInstance().id = parseInt(result[0]Usuario.getInstance().id = parseInt(result[0]

[["id""id"]); ]); Usuario.getInstance().nome = result[0]Usuario.getInstance().nome = result[0]

[["nome""nome"].toString();].toString(); Usuario.getInstance().usuario = result[0]Usuario.getInstance().usuario = result[0]

[["usuario""usuario"].toString();].toString(); Usuario.getInstance().permissao = Usuario.getInstance().permissao =

parseInt(result[0][parseInt(result[0]["permissao""permissao"]);]);}}

Fonte: Projeto antigo

Integração via RemoteObjectIntegração via RemoteObject

• Mesma velocidade de tráfego que o Mesma velocidade de tráfego que o HTTPService com AMFPHP;HTTPService com AMFPHP;

• Muito fácil de manipular os dados;Muito fácil de manipular os dados;• Muito fácil implementar os chamados para Muito fácil implementar os chamados para

o AMFPHP.o AMFPHP.

Porque o AMFPHPPorque o AMFPHP

• Muito fácil de utilizar;Muito fácil de utilizar;• Código aberto;Código aberto;• Comunidade ampla, facilitando a ajuda;Comunidade ampla, facilitando a ajuda;• Tempo de instalação praticamente zero.Tempo de instalação praticamente zero.

Vamos ao que interessaVamos ao que interessa

O AMFPHPO AMFPHP

Baixe-o em Baixe-o em http://www.amfphp.org/http://www.amfphp.org/ descompacte-o na pasta “src” e descompacte-o na pasta “src” e após isso aconselho a fazer após isso aconselho a fazer algumas modificações.algumas modificações.

Apagar os arquivos e pastas Apagar os arquivos e pastas desnecessários e principalmente desnecessários e principalmente renomear o gateway.php para renomear o gateway.php para index.phpindex.php

O Arquivo services-config.xmlO Arquivo services-config.xml

O arquivo services-config.xml é responsável pela O arquivo services-config.xml é responsável pela configuração do RemoteObject no Flex Builder.configuração do RemoteObject no Flex Builder.

Este arquivo deve ser passado como argumento na Este arquivo deve ser passado como argumento na compilação. Para isso você vai a compilação. Para isso você vai a Proprietes >> Proprietes >> Flex CompilerFlex Compiler e em e em additional compiler additional compiler arguments: arguments: e adicione o seguintee adicione o seguinte

-locale en_US -services "services-config.xml"-locale en_US -services "services-config.xml"

O Arquivo services-config.xmlO Arquivo services-config.xml<?<?xmlxml versionversion=="1.0""1.0" encodingencoding=="UTF-8""UTF-8"?>?>

<services-config><services-config>

<services><services>

<service<service idid=="amfphp-flashremoting-service""amfphp-flashremoting-service"

classclass=="flex.messaging.services.RemotingService""flex.messaging.services.RemotingService"

messageTypesmessageTypes=="flex.messaging.messages.RemotingMessage""flex.messaging.messages.RemotingMessage">>

<destination<destination idid==""CanalAmfphpCanalAmfphp"">>

<channels><channels>

<channel<channel refref=="my-amfphp""my-amfphp"/>/>

</channels></channels>

<properties><properties>

<source><source>**</source></source>

</properties></properties>

</destination></destination>

</service></service>

</services></services>

<channels><channels>

<channel-definition<channel-definition idid=="my-amfphp""my-amfphp"

classclass=="mx.messaging.channels.AMFChannel""mx.messaging.channels.AMFChannel">>

<endpoint<endpoint uriuri==""amfphp/amfphp/""

classclass=="flex.messaging.endpoints.AMFEndpoint""flex.messaging.endpoints.AMFEndpoint"/>/>

</channel-definition></channel-definition>

</channels></channels>

</services-config></services-config>

Destino da conexão

URL para conexão com o AMFPHP

Realizando uma conexãoRealizando uma conexãoprivateprivate functionfunction listar(): listar():voidvoid

{{

varvar remote:RemoteObject = remote:RemoteObject = newnew RemoteObject( RemoteObject("CanalAmfphp""CanalAmfphp"););

remote.showBusyCursor = remote.showBusyCursor = truetrue;;

remote.source = remote.source = "vo.UsuarioService""vo.UsuarioService";;

remote.addEventListener(ResultEvent.RESULT, resultListar)remote.addEventListener(ResultEvent.RESULT, resultListar)

remote.addEventListener(FaultEvent.FAULT, ErroListar)remote.addEventListener(FaultEvent.FAULT, ErroListar)

remote.getOperation(remote.getOperation("Listar""Listar").send();).send();

}}

privateprivate functionfunction ErroListar(e:FaultEvent): ErroListar(e:FaultEvent):voidvoid

{{

Alert.show(e.fault.faultString, Alert.show(e.fault.faultString,

e.fault.faultCode.toString());e.fault.faultCode.toString());

}}

privateprivate functionfunction resultListar(e:ResultEvent): resultListar(e:ResultEvent):voidvoid

{{

dgUsuarios.dataProvider = e.result dgUsuarios.dataProvider = e.result asas Array; Array;

}}

Apresentando os dadosApresentando os dados <mx:Button<mx:Button x=" x="1010" y="" y="1010" label="" label="Listar usuáriosListar usuários" click="listar()"" click="listar()"/>/>

<mx:DataGrid<mx:DataGrid x=" x="1010" y="" y="4040" width="" width="400400" id="" id="dgUsuariosdgUsuarios" "

itemClick="selecionaUsuario()" height="itemClick="selecionaUsuario()" height="144144"">>

<mx:columns><mx:columns>

<mx:DataGridColumn<mx:DataGridColumn headerText=" headerText="Nome completoNome completo" dataField="" dataField="NomeNome""/>/>

<mx:DataGridColumn<mx:DataGridColumn headerText=" headerText="E-mailE-mail" dataField="" dataField="EmailEmail""/>/>

<mx:DataGridColumn<mx:DataGridColumn headerText=" headerText="EndereçoEndereço" dataField="" dataField="EnderecoEndereco""/>/>

</mx:columns></mx:columns>

</mx:DataGrid></mx:DataGrid>

<mx:Label<mx:Label x=" x="1010" y="" y="208208" text="" text="ID:ID:" width="" width="110110" textAlign="" textAlign="rightright" " fontWeight="fontWeight="boldbold""/>/>

<mx:Label<mx:Label x=" x="1010" y="" y="234234" text="" text="Nome completo:Nome completo:" width="" width="110110" " textAlign="textAlign="rightright" fontWeight="" fontWeight="boldbold""/>/>

<mx:Label<mx:Label x=" x="1010" y="" y="260260" text="" text="E-mail:E-mail:" width="" width="110110" textAlign="" textAlign="rightright" " fontWeight="fontWeight="boldbold""/>/>

<mx:Label<mx:Label x=" x="1010" y="" y="286286" text="" text="Endereço:Endereço:" width="" width="110110" textAlign="" textAlign="rightright" " fontWeight="fontWeight="boldbold""/>/>

<mx:Label<mx:Label x=" x="128128" y="" y="208208" text="" text="{{selectedPerson.IDselectedPerson.ID}}""/>/>

<mx:Label<mx:Label x=" x="128128" y="" y="234234" text="" text="{{selectedPerson.NomeselectedPerson.Nome}}""/>/>

<mx:Label<mx:Label x=" x="128128" y="" y="260260" text="" text="{{selectedPerson.EmailselectedPerson.Email}}""/>/>

<mx:Label<mx:Label x=" x="126126" y="" y="286286" text="" text="{{selectedPerson.EnderecoselectedPerson.Endereco}}""/>/>

As classes UsuarioAs classes UsuarioA classe vo/Usuario.phpclassclass Usuario Usuario {{ varvar $_explicitType$_explicitType == "vo.Usuario""vo.Usuario";;

varvar $ID$ID;; varvar $Nome$Nome;; varvar $Email$Email;; varvar $Endereco$Endereco;;}}

A classe vo/Usuario.aspackagepackage vo vo{{ [RemoteClass(alias=[RemoteClass(alias="vo.Usuario""vo.Usuario")])] [[BindableBindable]] publicpublic classclass Usuario Usuario {{ publicpublic varvar ID:String; ID:String; publicpublic varvar Nome:String; Nome:String; publicpublic varvar Email:String; Email:String; publicpublic varvar Endereco:String; Endereco:String; }}}}

As classes UsuarioAs classes UsuarioA classe vo/Usuario.phpclassclass Usuario Usuario {{ varvar $_explicitType$_explicitType == "qualquerCoisaAqui""qualquerCoisaAqui";;

varvar $ID$ID;; varvar $Nome$Nome;; varvar $Email$Email;; varvar $Endereco$Endereco;;}}

A classe vo/Usuario.aspackagepackage vo vo{{ [RemoteClass(alias=[RemoteClass(alias="qualquerCoisaAqui""qualquerCoisaAqui")])] [[BindableBindable]] publicpublic classclass Usuario Usuario {{ publicpublic varvar ID:String; ID:String; publicpublic varvar Nome:String; Nome:String; publicpublic varvar Email:String; Email:String; publicpublic varvar Endereco:String; Endereco:String; }}}}

A classe UsuarioServiceA classe UsuarioService

requirerequire(("Usuario.php""Usuario.php"););

classclass UsuarioService UsuarioService

{{

functionfunction Listar Listar()()

{{

$retorno$retorno == '''';;

$retorno$retorno[][] == newnew Usuario Usuario((11,, "Eduardo Kraus""Eduardo Kraus",, "[email protected]""[email protected]",, "Palhoça SC""Palhoça SC"););

$retorno$retorno[][] == newnew Usuario Usuario((22,, "Usuarios 2""Usuarios 2",, "[email protected]""[email protected]",, "Florianópolis SC""Florianópolis SC"););

$retorno$retorno[][] == newnew Usuario Usuario((33,, "Estagiario""Estagiario",, "[email protected]""[email protected]",, "São "São José SC"José SC"););

returnreturn $retorno$retorno;;

}}

}}

A aplicaçãoA aplicação

A aplicaçãoA aplicação

A aplicaçãoA aplicação

[[BindableBindable] ] privateprivate varvar selectedPerson:Usuario; selectedPerson:Usuario; privateprivate functionfunction listar(): listar():voidvoid{{ varvar remote:RemoteObject = remote:RemoteObject = newnew RemoteObject( RemoteObject("CanalAmfphp""CanalAmfphp");); remote.showBusyCursor = remote.showBusyCursor = truetrue;; remote.source = remote.source = "vo.UsuarioService""vo.UsuarioService";; remote.addEventListener(ResultEvent.RESULT, resultListar)remote.addEventListener(ResultEvent.RESULT, resultListar) remote.addEventListener(FaultEvent.FAULT, ErroListar)remote.addEventListener(FaultEvent.FAULT, ErroListar) remote.getOperation(remote.getOperation("Listar""Listar").send();).send(); }} privateprivate functionfunction ErroListar(e:FaultEvent): ErroListar(e:FaultEvent):voidvoid{{ Alert.show(e.fault.faultString, e.fault.faultCode.toString());Alert.show(e.fault.faultString, e.fault.faultCode.toString()); }} privateprivate functionfunction resultListar(e:ResultEvent): resultListar(e:ResultEvent):voidvoid{{ dgUsuarios.dataProvider = e.result dgUsuarios.dataProvider = e.result asas Array; Array; }} privateprivate functionfunction selecionaUsuario(): selecionaUsuario():voidvoid{{ selectedPerson = Usuario(dgUsuarios.selectedItem);selectedPerson = Usuario(dgUsuarios.selectedItem); }} <mx:Button<mx:Button x=" x="1010" y="" y="1010" label="" label="Listar usuáriosListar usuários" click="listar()"" click="listar()"/>/> <mx:DataGrid<mx:DataGrid x=" x="1010" y="" y="4040" width="" width="400400" id="" id="dgUsuariosdgUsuarios" " itemClick="selecionaUsuario()" height="itemClick="selecionaUsuario()" height="144144"">> <mx:columns><mx:columns> <mx:DataGridColumn<mx:DataGridColumn headerText=" headerText="Nome completoNome completo" dataField="" dataField="NomeNome""/>/> <mx:DataGridColumn<mx:DataGridColumn headerText=" headerText="E-mailE-mail" dataField="" dataField="EmailEmail""/>/> <mx:DataGridColumn<mx:DataGridColumn headerText=" headerText="EndereçoEndereço" dataField="" dataField="EnderecoEndereco""/>/> </mx:columns></mx:columns> </mx:DataGrid></mx:DataGrid> <mx:Label<mx:Label x=" x="128128" y="" y="208208" text="" text="{{selectedPerson.IDselectedPerson.ID}}""/>/> <mx:Label<mx:Label x=" x="128128" y="" y="234234" text="" text="{{selectedPerson.NomeselectedPerson.Nome}}""/>/> <mx:Label<mx:Label x=" x="128128" y="" y="260260" text="" text="{{selectedPerson.EmailselectedPerson.Email}}""/>/> <mx:Label<mx:Label x=" x="126126" y="" y="286286" text="" text="{{selectedPerson.EnderecoselectedPerson.Endereco}}""/>/>

Podemos melhorar a conexãoPodemos melhorar a conexãoCriar uma classe global que fará a conexão e em caso de Criar uma classe global que fará a conexão e em caso de

erro apresente em um Alert e em sucesso retorne para a erro apresente em um Alert e em sucesso retorne para a nossa função:nossa função:

publicpublic classclass RemoteObjectAMFPHP RemoteObjectAMFPHP extendsextends RemoteObject{ RemoteObject{

publicpublic functionfunction RemoteObjectAMFPHP(): RemoteObjectAMFPHP():voidvoid{{

supersuper(("CanalAmfphp""CanalAmfphp"))

}}

publicpublic functionfunction Remoto(_source:String, result:Function): Remoto(_source:String, result:Function):voidvoid{{

thisthis.source = _source;.source = _source;

thisthis.showBusyCursor = .showBusyCursor = truetrue;;

thisthis.addEventListener(ResultEvent.RESULT, result);.addEventListener(ResultEvent.RESULT, result);

thisthis.addEventListener(FaultEvent.FAULT, Falha);.addEventListener(FaultEvent.FAULT, Falha);

}}

privateprivate functionfunction Falha(e:FaultEvent): Falha(e:FaultEvent):voidvoid{{

Alert.show(e.fault.faultString, e.fault.faultCode.toString());Alert.show(e.fault.faultString, e.fault.faultCode.toString());

}}

}}

Podemos melhorar a conexãoPodemos melhorar a conexão

Deste modo a chamada fica mais Deste modo a chamada fica mais simples:simples:

privateprivate functionfunction listar(): listar():voidvoid{{

varvar remote:RemoteObjectAMFPHP = remote:RemoteObjectAMFPHP = newnew RemoteObjectAMFPHP() RemoteObjectAMFPHP()

remote.Remoto(remote.Remoto("vo.UsuarioService""vo.UsuarioService", resultListar);, resultListar);

remote.getOperation(remote.getOperation("Listar""Listar").send();).send();

}}

privateprivate functionfunction resultListar(e:ResultEvent): resultListar(e:ResultEvent):voidvoid{{

dgUsuarios.dataProvider = e.result dgUsuarios.dataProvider = e.result asas Array; Array;

}}

Falando de segurançaFalando de segurança

Nunca estamos seguros o suficienteNunca estamos seguros o suficiente

Métodos abertosMétodos abertos• Cuidado com métodos que somente serão Cuidado com métodos que somente serão

acessados por usuário logado;acessados por usuário logado;• Cuidado com classes que manipulam banco Cuidado com classes que manipulam banco

de dados, nunca as deixe dentro da pasta de dados, nunca as deixe dentro da pasta “services”;“services”;

• Cuidado com métodos que apagam arquivos;Cuidado com métodos que apagam arquivos;• Nunca envie as senhas, mesmo Nunca envie as senhas, mesmo

criptografadas, nos métodos que os listam.criptografadas, nos métodos que os listam.• Antes de publicar não esquerça de apagar as Antes de publicar não esquerça de apagar as

pastas amfphp/browser e pastas amfphp/browser e amfphp/services/amfphpamfphp/services/amfphp

Sempre o UploadSempre o Upload

Quem que não tem um arquivo upload.php Quem que não tem um arquivo upload.php com o seguinte conteudo?com o seguinte conteudo?

<?php<?php

$strOrigem$strOrigem == $_FILES$_FILES[['Filedata''Filedata']] [['tmp_name''tmp_name'];];

$strDestino$strDestino == "../upload/""../upload/"..$_FILES$_FILES[['Filedata''Filedata'][]['name''name'];];

ifif(!(!move_uploaded_file move_uploaded_file (($strOrigem$strOrigem,, $strDestino$strDestino)){)){

$erroUp$erroUp->->erroerro(("Erro ao mover""Erro ao mover"););

}}

elseelse{{

$erroUp$erroUp->->erroerro(("Movido com sucesso""Movido com sucesso"););

}}

?>?>

PerguntasPerguntas

??

Para onde ir agoraPara onde ir agora• http://blog.mxml.com.br/http://blog.mxml.com.br/• http://www.amfphp.org/http://www.amfphp.org/• http://www.adobe.com/devnet/flex/http://www.adobe.com/devnet/flex/• http://www.adobe.com/devnet/flex/tourdeflex/http://www.adobe.com/devnet/flex/tourdeflex/• http://www.adobe.com/devnet/flex/flex_php.htmlhttp://www.adobe.com/devnet/flex/flex_php.html• http://flex.org/http://flex.org/• http://livedocs.adobe.com/flex/3/langref/http://livedocs.adobe.com/flex/3/langref/• http://livedocs.adobe.com/flex/3/html/http://livedocs.adobe.com/flex/3/html/• http://opensource.adobe.comhttp://opensource.adobe.com