Olá Pessoal,
Um item básico quando se trata de sites, é um local onde o visitante pode de alguma forma entrar em contato com a empresa do site, hoje existem algumas boas soluções para isso, como por exemplo um client msn que pode ser colocado no site e se o visitante quiser, pode entrar em contato com o msn da empresa.
Mas hoje vou mostrar a vocês uma forma simples e funcional, que consiste em um formulário onde o visitante preenche os dados, e gera um e-mail para o destinatário.
Mostrarei isso usando PHP/ZEND/AMFPHP/FLEX, poderia fazer isso somente com HTTPService? concerteza, ficaria menos código e até mais simples, porém concordamos que ninguém iria fazer uma aplicação só com essa funcionalidade, pois o Formulário de Contato seria apenas um módulo do sistema.
Então vou lhes mostrar também uma proposta de como você pode trabalhar arquiteturalmente com Flex e PHP, trocando apenas VO/TO/DTO entre as camadas, lembrando que isso é uma boa prática, vejo muitos porae trocando array’s com Flex e PHP, isso é totalmente desnecessário.
Detalhes da Arquitetura
A arquitetura usa o ZEND para abstração do banco de dados usando a Classe Zend_Db_Table, e outros recursos como o Zend_Loader e Zend_Registry.
AMFPHP para a comunicação entre o AdobeFlex e o PHP, esta comunicação rodando em cima do protocolo AMF3, que provém comunicação binária não mais String como no HTTP puro, e também compactação.
Estruturando a aplicação
Crie uma estrutura de pastas como mostrado na Listagem 1
O package entitybean contém classes que segue os conceitos de um EntityBean como nas especificações J2EE/JEE, só que claro BMP através do Zend_Db_Table, e uma outra classe que eu fiz chamada EntityBeanImpl, que abstrai ainda mais os métodos CRUD de um caso de uso, como por Exemplo eliminei os métodos Inserir e Atualizar, e criei um Salvar, que insere ou atualiza baseado na Primary-Key. Em poucas palavras, um EntityBean, é reponsável pela abstração de um Banco de Dados Relacional, as camadas acima de entityBean apenas conhecem o entitybean, não tem acesso ao Banco de dados.
Para Garantir transação e concorrência, criei uma classe chamada DB que cotém um singleton me garantindo apenas uma instância da mesma em uma transação, ela é reponsavel por iniciar uma transação através do método beginTransaction() realizar o commit se toda a operação ocorrer com sucesso atraveés do método commit() e realizar o roolback no banco de dados através do método rollback().
O package sessionbean contém classes que segue os conceitos de um SessionBean também como nas especificações J2EE/JEE só que apenas sendo Stateless. Em poucas palavras um SessionBean tem a responsábilidade de implementar a regra de negócio do caso de uso, como por exemplo validações, calculos e etc.
O package facade contém classes que implementam o Pattern Facade em outras palavras é a fachada do sistema, neta arquitetura ela é responsável por garantir a transação usando a classe DB, também é reponsável pelo tratamento de exceções (Erros).
O package vo contém simples classes que implementam os Patterns VO/TO/DTO, são os vo’s encarregados de transportar entre as camadas as informações de cada caso de uso. Lembrando que o mesmo VO no PHP, será automaticamente serializado pelo AMFPHP para um VO no Flex para isso os VO devem ficar assim:
No PHP:
*Coloque a tag do php no inicio e no fim.
[php]
class ContatoVO
{
var $idContato;
var $dsNome;
var $dsEmail;
var $nuTelefone;
var $dsCidade;
var $dsEstado;
var $dsMensagem;
//NOME DO VO NO FLEX
var $_explicitType = “ContatoVO”;
}
[/php]
No Flex/AS3
[as]
package com.digows.Artigos.FlexPHP.vo
{
//NOME DO VO NO PHP
[RemoteClass(alias=”ContatoVO”)]
[Bindable]
public class ContatoVO
{
public var idContato:int;
public var dsNome:String;
public var dsEmail:String;
public var nuTelefone:String;
public var dsCidade:String;
public var dsEstado:String;
public var dsMensagem:String;
}
}
[/as]
O package services contem as classes de serviços de toda aplicação, estes serviços podem ser disponibilizados para o AMFPHP como veremos a seguir, ou também se você conhece bem o Zend Framework, pode gerar serviços através de WebServices ou até mesmo serviços para o Controller do Zend Framework, neste caso usando HTML na View.
O package config apenas contém arquivos de configuração, como por exemplo path do servidor, dados do banco de dados e etc.
E finalmente o package libs que contém as bibliotecas utilizadas na aplicação, no caso o AMFPHP e Zend Framework.
Configurando a aplicação
Nós precisamos fazer uma integração com o Zend Framework, e o AMFPHP, então primeiramente vamos gerar o application-config.php do Zend.
Dentro do package config, crie um arquivo chamado application-config.php com este conteúdo:
*Coloque a tag do php no inicio e no fim.
[php]
set_include_path(‘.’.PATH_SEPARATOR.’../../libs’.PATH_SEPARATOR.get_include_path());
require_once (‘Zend/Loader.php’);
/**
* Loaders
*/
//Registrador de Variaveis
Zend_Loader::loadClass(‘Zend_Registry’);
//Carregador de configuracoes de um .ini
Zend_Loader::loadClass(‘Zend_Config_Ini’);
//Classe que encapsula o Banco
Zend_Loader::loadClass(‘Zend_Db’);
//Classe para usar as tabelas como objetos.
Zend_Loader::loadClass(‘Zend_Db_Table’);
//Usada para fazer o parser dos xml
Zend_Loader::loadClass(‘Zend_Config_Xml’);
/**
* Configuracoes da Persistencia.
*/
//Carrega o arquivo de configuracoes.
$configDB = new Zend_Config_Ini(dirname(__FILE__).’/config.ini’, ‘database’);
Zend_Registry::set(‘configDB’, $configDB);
$configPaths = new Zend_Config_Ini(dirname(__FILE__).’/config.ini’, ‘paths’);
Zend_Registry::set(‘configPaths’, $configPaths);
/**
* Configuracoees variadas…
*/
//Configura o formato para moeda
setlocale(LC_MONETARY, ‘ptb’);
//Configura as mensagens de erro que devem ser apresentadas.
error_reporting(E_ALL | E_STRICT);
[/php]
Perceba que a configuração usa um arquivo chamado config.ini este contém as configurações do Banco de Dados e paths:
[database] db.adapter=PDO_MYSQL db.config.host=localhost db.config.username=root db.config.password= db.config.dbname=flexphp [paths] path.dirImg=C:/resources/img
No package libs você coloca os arquivos do ZEND e do AMFPHP ficando assim:
A única coisa que precisa ser feita com o AMFPHP, é dizer a ele aonde está os services, que usa para mandar os VO’s para o PHP, e aonde se encontra o package dos VO’s, que ele usa para serializar os VO’s Flex e PHP.
Para isso, abra o arquivo globals.php dentro da pasta do AMFPHP e deixe assim:
*Coloque a tag do php no inicio e no fim.
[php]
//This file is intentionally left blank so that you can add your own global settings
//and includes which you may need inside your services. This is generally considered bad
//practice, but it may be the only reasonable choice if you want to integrate with
//frameworks that expect to be included as globals, for example TextPattern or WordPress
//Set start time before loading framework
list($usec, $sec) = explode(” “, microtime());
$amfphp[‘startTime’] = ((float)$usec + (float)$sec);
$servicesPath = “../../application/services/”;
$voPath = “../../application/business/vo/”;
//As an example of what you might want to do here, consider:
/*
if(!PRODUCTION_SERVER)
{
define(“DB_HOST”, “localhost”);
define(“DB_USER”, “root”);
define(“DB_PASS”, “”);
define(“DB_NAME”, “amfphp”);
}
*/
[/php]
Perceba as variaveis $servicesPath e $voPath.
É preciso configurar os sources_paths do projeto no caso o src_flex e src_php, para isso:
No seu projeto de um botão direito -> Properties -> Selecione a opção Flex Build Path -> clique no botão Add Folder e procure a pasta src_php -> Em Main source folder selecione a pasta src_flex.
Esta tela deverá ficar assim:
E para concluir, precisamos informar ao compilador Flex qual o endereço do gateway onde será possível trocar dados em cima do protocolo AMF3, para isso gere um arquivo com o nome de services-config.xml na raiz da pasta src_flex com este conteúdo:
XML
1: <services-config>
2: <services>
3: <service id="amfphp-flashremoting-service"
4: class="flex.messaging.services.RemotingService"
5: messageTypes="flex.messaging.messages.RemotingMessage">
6: <destination id="amfgateway">
7: <channels>
8: <channel ref="channel-amf"/>
9: </channels>
10: <properties>
11: <scope>session</scope>
12: <source>*</source>
13: </properties>
14: </destination>
15: </service>
16: </services>
17: <channels>
18: <channel-definition id="channel-amf" class="mx.messaging.channels.AMFChannel">
19: <endpoint uri="http://{server.name}:{server.port}/FlexPHP/libs/amfphp/gateway.php"
20: class="flex.messaging.endpoints.AMFEndpoint"/>
21: </channel-definition>
22: </channels>
23: </services-config>
E nos Properties do Projeto, o FlexCompiler deverá ficar assim:
Listagem 4
Detalhando as Camadas
O Fluxo das Camada é a seguinte:
O Flex chama um Serviço através do AMFPHP que direciona para uma classe com um especifico método no package services;
Ex: O Flex Chama a classe ContatoService, solicitando o método save(), passando por parâmentro uma instância de ContatoVO.
A Service chama uma classe da Facade com o respectivo método solicitado;
Ex: O ContatoService chama o ContatoFacade solicitando o método save() passando por parâmentro uma instância de ContatoVO.
A Facade abre uma transação, e chama um SessionBean;
Ex: O ContatoFacade chama o ContatoBean solicitando o método save() passando por parâmentro uma instância de ContatoVO.
O SessionBean faz a regra de negócio específica do caso de uso, e se tudo tiver ok chama um EntityBean para fazer a persistência, se não dispara uma nova Exception dando rollback no banco e mostrando uma mensagem de erro para o Flex através do catch na Facade;
Ex: O ContatoSession chama o ContatoBean solicitando para que insira ou atualize os dados através do ContatoVO passado por parâmentro.
Tendo conhecimento do Fluxo das camadas pode se observar que o código ficou bem separado, o que garante baixo acoplamento e alta coesão.
E como Fica no Flex?
Como este exemplo tem por finalidade de mostrar uma proposta de arquitetura com Flex e PHP, este exemplo não adota padrões de projetos no lado Flex, mas é extremamente recomendável o uso de Padrões seja com o Cairngorm da Adobe ou tantos outros existentes porae.
A classe RemoteConnection é uma classe que tem por finalidade de abstrair o uso do RemoteObject, como por exemplo você pode chamar o ContatoService desta forma:
[as]
var contatoVO:ContatoVO = new ContatoVO();
contatoVO.dsNome = txtNome.text;
contatoVO.dsEmail = txtEmail.text;
contatoVO.nuTelefone = txtTelefone.text;
contatoVO.dsCidade = txtCidade.text;
contatoVO.dsEstado = txtEstado.text;
contatoVO.dsMensagem = txtMensagem.text;
RemoteConnection.call(“ContatoService”,”save”,
function(event:ResultEvent):void
{
Alert.show(“Email enviado com sucesso!”,”SUCESSO!”);
clear();
},
contatoVO
);
[/as]
Perceba que gero um VO com as informações da Tela, e Solicito o serviço ContatoService chamando o método save() passando por parâmetro uma instância de ContatoVO.
A Função de retorno implementei dentro do próprio método, mas eu poderia criar uma função só para tratar o retorno do método assíncrono.
Bom Senhores, acredito que consegui dar uma boa explicação sobre como trabalhar arquiteturalmente com Flex e PHP.
Estarei diponibilizando o projeto usado no exemplo, para executar, dentro da pasta docs contém 2 arquivos, um chamado localhost.sql.zip que pode ser usado para gerar o banco de dados e outro chamado MER.xml que é o MER feito com o DBDesigner. Após gerar o banco, é só importar no seu Flex Builder 3.
Aplicação Rodando
Source do Projeto: Projeto FlexPHP
Para aqueles que tiverem dúvidas, sujestões ou críticas podem entrar em contato comigo, na medida do possível estarei lhes respondendo.
Obrigado a Todos e um Bom Proveito!
Liz.. te amo querida! =*
Parabéns Rodrigo, muito bom!
Graças a Deus, o paradigma da OOP vem se fortalecendo muito no mundo PHP, no meu tempo, era pecado usar OOP no php4.. hehehe.
Só tenho uma pqna ressalva, mas q vale a análise de cada caso de uso: o framework.
Acho o Zend um framework muito grande até para projetos de médio porte. Talvez vc conseguisse simplificar muito aplicando o conceito de MVC mais puramente e com um DAO genérico, ou até mesmo usar um ORM como o Lumine que simplifica bastante o lado do PHP.
Mas como disse antes, vale a análise de cada caso, se o projeto realmente for grande, daí o uso do Zend Framework vale a pena.
Abraços, e novamente parabéns cara.
LikeLike
muito bom, gostei
parabens =]
LikeLike
Parabéns, excelente fonte de referência….
LikeLike
Eu concordo com o Mário, talvez o Zend seja um tiro de bazuka numa mosca…
Aqui o cakePHP nao te atendeu nao ?
ou quem sabe o RoR 🙂
LikeLike
Hi ,
I have been really looking for FLEX AND SPRING , HIBERNATE samples to work with, but I don’t understand the languge would it be possible to have english version.
thanks
LikeLike
Hi!
In my blog, I only posted integrating
AdobeFlex + ZendFramework + AMFPHP.
It few days, I will post an article integrating
AdobeFlex + BlazeDS + Hibernate + SpringFramework.
But at the time, what do you really have doubt?
LikeLike
Parabéns cara, ficou muito bom!
LikeLike
Odeio flash!
LikeLike
Dante…
Só um detalhe, Flex não é Flash! na verdade não tem nada haver mesmo!
Eu mesmo não gosto do timeline do Flash nem sei mecher direito naquilo…
Mas amo programar orientado a objetos com Flex!
Abraços
o/
LikeLike
Sim. Flex não é Flash, mas usa o plugin do tal…
Para o usuário final é um Flash.
Veja como seu exemplo ficou aqui no meu IE 7 64bits que não tem suporte ao Plugin do Flash ainda.
Alternate HTML content should be placed here. This content requires the Adobe Flash Player. Get Flash
LikeLike
Pingback: Tony Ngo » Blog Archive » Zend Framework and AMFPHP
Pingback: Manifesto Flex brasil - Rodrigo Fraga - RIA Evangelist
E porque não simplificar só com Flex + AMFPHP + PHP e fim !???
LikeLike
mano, gostei demais de sua aplicacao, so nao consegui baixar o codigo fonte para estudo, sou novato em flex, poderia me consguir um link pra baixar, este do site da erro 404…
LikeLike
Alguem tem o source.zip deste exemplo???
LikeLike
Rodrigo, poderia me disponibilizar o código fonte do exemplo?Obrigado
LikeLike
Dae rodrigo eu gostaria do código fonte também.
[]´s
LikeLike
Rodrigo, grande artigo. Como iniciante em flex, deu uma grande forca. Nao consegui abrir o link do exemplo. Tem o source pra envio ou link pra download.
Grande forca e obrigado
LikeLike
Realmente, muito bom! Usar Design Patterns sempre é bom. Poderia me enviar, ou disponibilizar o source?
Grato e Parabéns!
LikeLike
@Rodrigo Pereira Fraga
Tenho que discordar com você.
Trabalhei com Flash por 3 anos, e agora com Flex 2/3 por 2 anos.
E ambos são a mesma coisa.
Claro, muda totalmente a forma de programar (um tem a timeline que você odeia, e outro usa o drag n’ drop de componentes) mas ambos são iguais…
A linguagem é a mesma, e o que você consegue fazer em um, teoricamente consegue fazer no outro também. Algumas coisas com mais trabalho, outras com menos.
LikeLike
olá Rodrigo!
vc poderia disponibilizar o código pra download, pois nao estou conseguindo baixar o mesmo!!!
e uma dica,
vc poderia fazer o mesmo exemplo usando a nova versao do zf que agora ja vem com o amfphp incluso…
abraços
e parabéns pelo blog
LikeLike
Bom quem Odeia o Flesh é porque não conhece o programa, é a coisa mais completa que já criaram, da para programar, da para desenhar, da para animar, o flesh só volta comprar pão.
mas tem gente que tem medo da interface do programa oO. ou tem ódio de design!
LikeLike
Muito legal, esta me ajudando em meu inicio de integracao do php com o flex.
mesmo sabendo que não pretendo criar um formulario de contato no flex.
valew
LikeLike
nao estou conseguindo fazer o download do Source do Projeto. podem me ajudar ai, ou mandar pro meu email alguem que ja conseguiu baixar: matusalemcassim@gmail.com
LikeLike
Belo trabalho.
Poderia disponibilizar se possivel o codigo, pois no link postado no tutoria não está disponível.
Obrigado.
LikeLike
Acho que a maior (e melhor) vantagem do Flex em Relação ao Flash é o preço! xD
Já sobre o ZF, discordo de quem disse que é exagero usa-lo em pequenos/medios projetos.
Até por que na versão atual, fica muito fácil criar webservice tanto usando AMF quanto SOAP/WSDL sem precisar alterar as classes dos serviços.
Vale a pena dar uma conferida na nova versão!
E muito legal seu artigo, algumas coisas eu prefiro fazer de uma outra forma, mas sempre é bom conhecer outras formas de criar.
LikeLike
Na lata.. Muito Bao!!!
LikeLike
More good stuff!
LikeLike
Resources similar to the one you described here is going to be very beneficial to me personally! I will post a website link to this web page on my weblog. Read my website visitors will find that really beneficial.
LikeLike
It seems to me that this web site doesn
LikeLike
This report is undoubtedly exciting. I have bookmarked the website for future visits at the same time. Cheers !
LikeLike
It seems to me that this site doesn
LikeLike
Oh man. This site is awesome. How did you make it look like this ?
LikeLike
Thank you for that wise critique. Me & my neighbour were preparing to do some research about that. We got a good book on that matter from our local library and most books where not as influensive as your information and facts. I’m quite glad to see this kind of information and facts which I was searching for a long time.
LikeLike
This website has a lot of very useful info on it! Thank you for helping me.
LikeLike
Hey Yawl I read the information you posted here and I wanted to say you guys need to continue to add more content. It’s extremely interesting to us readers and I will probably be back. I will write about with my friends. Keep it rolling!
LikeLike