Sie sind auf Seite 1von 43

http://www.pauloeduardo.

com/2011/02/09/criando-um-projeto-com-zend-framework/
Criando Um Projeto Com Zend Framework
No post anterior fiz um Comparativo entre CodeIgniter e Zend Framework, os dois frameworks de
desenolimento em !"! com os #uais eu mais tra$alhei e tenho mais e%peri&ncia, como disse o
'ode()niter a tempos n*o em sendo atualizado e dei%ou de ser uma $oa alternatia para
desenolimento de aplica+,es de )rande porte com !"!, por isso passei a usar cada ez mais
o Zend Framework.
-rti)os so$re como come+ar com .end /ramework podem ser encontrados aos montes pela
internet, posso citar a#ui al)uns como o tutorial Getting Started with Zend Framework pu$licado
por 0o$ -llen, #ue talez seja o mais famoso deles e outros como Zend Framework Tutorial
Series, Como Criar Um Projeto Usando O Zend Tool do Zend Framework ou Zend In!io cada um deles
com uma enfase e a$roda)em diferente, al)uns deles j1 desatualizados por conta da elocidade de
atualiza+,es do pr2prio framework. 3as se j1 e%istem tantos assim, por #ue escreer mais um4
5om, meu intuito com esse arti)o e proporcionar uma a$orda)em mais simples #ue as
fre#uentemente mostrandas, #ue e%istem diferentes formas de montar a estrutura do seu projeto
com .end /ramework, e #ue esteja atualizada com a ers*o 1.11.% do /ramework 6a ers*o est1el
mais recente at7 esse momento8.
Instalao do Ambiente
-ntes de iniciar o desenolimento de aplica+,es com .end /ramework, ou presumir #ue oc& j1
tenha al)uma e%peri&ncia com !"!, e tam$7m #ue tenha um am$iente de desenolimento com
um seridor we$ 6preferencialmente apache8 funcionando com php, um $anco de dados instalado
n*o 7 o$ri)at2rio, mas ser1 necess1rio para construir aplica+,es maiores com acesso a dados.
'aso oc& n*o tenha esse am$iente preparado oc& poder1 instal1-los indiidualmente indo aos
sites da "pa!he Foundation e do P#P, al7m do site do seu $anco de dados de prefer&ncia, e $ai%ar
as 9ltimas ers,es dos softwares e instal1-los, al7m dessa forma e%istem al)uns pacotes prontos
com todas essas aplica+,es para oc& realizar uma 9nica instala+*o, um desses pacotes 7 o Zend
Server #ue j1 inlcui o .end /ramework no site da .end.
Download do Zend Framework
:e oc& realizou a instala+*o do .end :erer como dito acima, o download e instala+*o do .end
/ramework j1 foi realizado junto com ele, caso contr1rio oc& dee ir a P$gina de %ownloads do
.end /ramework e $ai%ar preferencialmente o /ull !acka)e, oc& $ai%ar1 um ar#uio compactado
contendo a pasta $in, onde est1 o zend tool, a pasta li$rar; onde est*o de fato os ar#uios do
framework, e diersas outras pastas contendo e%emplos e $i$liotecas de terceiros #ue n*o s*o
releantes para esse arti)o.
Criao da Estrutura de Diretrios do Zend Framework
/i). 1 - <strutura de =iret2rios do .end /ramework
> .end /ramework permite #ue oc& crie praticamente #ual#uer estrutura para armazenar os
ar#uios #ue de fato comp,em sua aplica+*o, na minha opini*o isso mais dificulta do #ue facilita o
aprendizado com .end /ramework, pois o desenoledor iniciante, na $i$lioteca, fica meio perdido
com rela+*o a como montar a melhor estrutura para tra$alhar com o framework. /elizmente para
isso e%iste uma estrutura recomendada pela .end 6fi) 18 e 7 utilizando essa estrutura #ue amos
tra$alhar nesse tutorial.
<%istem diersas formas de se criar essa estrutura, cada uma delas mais f1cil #ue a outra, mas #ue
*o depender das ferramentas #ue oc& est1 utilizando.
Zend Tool
> primeiro modo de criar a estrutura de diret2rios do .end /ramework e utilizando o .end ?ool,
caso oc& n*o tenha confi)urado seu am$iente com .end :erer, antes de utilizar o .end ?ool, oc&
deer1 copiar os ar#uios do .end ?ool #ue est*o localizados na pasta $in, juntamente com os
outros ar#uios $ai%ados do .end /ramework, para a pasta de ar#uios $in1rios dentro da sua
instala+*o do !"!.
No caso de am$ientes @inu% e Ani% essa pasta )eralmente est1 localizada em um dos se)uintes
caminhos:
/usr/$in
/usr/local/$in
/usr/local/.end:erer/$in/
/-pplications/.end:erer/$in/
No caso de am$ientes Bindows essa pasta )eralmente est1 localizada em um dos se)uintes
caminhos:
':C!"!
':C!ro)ram /ilesC.end:ererC$inC
':CB-3!C!"!C$in
'aso oc& tenha instalado o .end :erer isso j1 foi feito automaticamente junto com a instala+*o
-)ora #ue o .end ?ool j1 foi instalado no sistema e adicionado como uma ari1el path, tudo #ue
oc& ter1 #ue fazer para criar a estrutura de diret2rios para o .end /ramework 7 a$rir seu console,
ou prompt de comando nae)ar at7 a pasta onde deseja criar a estrutura de diret2rios 6isso pode
ariar entre Bindows, @inu% e 3ac>: e pode e%i)ir um pouco de conhecimento em linha de
comando, mas n*o t*o complicado assim8 e di)itar o comando a se)uir su$stituindo nome-do-
projeto pelo nome do seu projeto:
zf create project nome-do-projeto
!or fim oc& dee erificar se a pasta .end foi copiada para dentro do diret2rio li$rar; criado pelo
comando acima, caso ela tenha sido copiada j1 est1 tudo certo, caso contr1rio $asta copi1-la de
dentro do diret2rio li$rar;, incluido junto com o .end /ramework #ue oc& haia $ai%ado e
descompactado. Doc& tam$7m pode copiar essa pasta para dentro do includeEpath do seu !"!, e
com isso poder1 utilizar o .end /ramework em 1rios projetos sem ter #ue copi1-lo para cada um
deles.
Zend Studio
>utra forma de criar a estrutura de diret2rios necess1ria para se desenoler com .end :erer 7
utilizando o .end :tudio, o .end :tudio 7 uma (=< de desenolimento $aseada em eclipse e
desenolida pela pr2pria zend e pode ser ad#uirida na p1)ina do Zend Studio. -p2s ad#uirir e
instalar o .end :tudio tudo #ue oc& precisa fazer 7 clicar em /ile-FNew-F.end /ramework
!roject, preencher o campo nome com o nome do projeto e clicar em G/inishH. 5asicamente o #ue
a ferramenta faz 7 chamar o zend tool, #ue foi instalado juntamente com ela, e e%ecutar o mesmo
comando do item anterior, mas dessa forma oc& n*o precisa sa$er a$solutamente nada so$re linha
de comando ou confi)ura+*o de ari1eis de sistema.
anualmente
!ara realizar a cria+*o da estrutura manualmente oc& precisar1 criar toda a estrutura de pastas
manualmente, conforme mostrado na fi)ura 1 acima e alterar #uatro ar#uios, o primeiro deles o
ar#uio inde%.php localizado no diret2rio pu$licincluindo a se)uinte se#I&ncia de c2di)o:
J4php
// Define path to application directory
defined('APPLICATIONPAT!'"
## define('APPLICATIONPAT!'$ realpath(dirname(%IL&" '
'/''/application'""(
// Define application en)ironment
defined('APPLICATION&N*'"
## define('APPLICATION&N*'$ (+eten)('APPLICATION&N*'" ,
+eten)('APPLICATION&N*'" - 'prod.ction'""(
// &n/.re li0rary/ i/ on incl.depath
/etincl.depath(implode(PAT!1&PA2ATO2$ array(
realpath(APPLICATIONPAT! ' '/''/li0rary'"$
+etincl.depath("$
"""(
/33 4endApplication 3/
re5.ireonce '4end/Application'php'(
// Create application$ 0oot/trap$ and r.n
6application 7 ne8 4endApplication(
APPLICATION&N*$
APPLICATIONPAT! ' '/confi+//application'ini'
"(
6application-90oot/trap("
-9r.n("(
<sse 7 o ar#uio #ue ir1 iniciar a sua aplica+*o,e $asicamente o #ue ele faz 7 confi)urar onde est*o
todos os diret2rios e ar#uios necess1rios para iniciar sua aplica+*o, confi)urar o am$iente e
iniciar a aplica+*o de fato.
> se)undo 7 o ar#uio $ootstrap.php no diret2rio application com o se)uinte c2di)o:
:,php
cla// ;oot/trap e<tend/ 4endApplication;oot/trap;oot/trap
=
>
<sse ar#uio 7 o ar#uio de 5ootstrap da aplica+*o, nele oc& poder1 incluir $asicamente tudo #ue
for necess1rio para ser inciado juntamente com a aplica+*o.
0epare #ue em nenhum dos dois ar#uios a ta) !"! 7 fechada, isso 7 feito propositalmente para
eitar o enio de informa+,es para o nae)ador.
-l7m disso oc& dee alterar o ar#uio application.ini dentro do diret2rio confi) com a se)uinte
informa+*o:
?prod.ction@
php1ettin+/'di/play/tart.perror/ 7 A
php1ettin+/'di/playerror/ 7 A
incl.dePath/'li0rary 7 APPLICATIONPAT! B/''/li0raryB
0oot/trap'path 7 APPLICATIONPAT! B/;oot/trap'phpB
0oot/trap'cla// 7 B;oot/trapB
appname/pace 7 BApplicationB
re/o.rce/'frontController'controllerDirectory 7 APPLICATIONPAT!
B/controller/B
re/o.rce/'frontController'param/'di/play&<ception/ 7 A
?/ta+in+ - prod.ction@
?te/tin+ - prod.ction@
php1ettin+/'di/play/tart.perror/ 7 C
php1ettin+/'di/playerror/ 7 C
?de)elopment - prod.ction@
php1ettin+/'di/play/tart.perror/ 7 C
php1ettin+/'di/playerror/ 7 C
re/o.rce/'frontController'param/'di/play&<ception/ 7 C
No arti)o anterior eu escrei so$re como criar um projeto com zend framework mostrando #ue
e%istem diersas formas de se criar essa estrutura de projeto e #ue o .end permite ainda #ue oc&
utilize diferentes estruturas de diret2rios para se ade#uar melhor as suas necessidades, se oc&
$ai%ou o ar#uio compactado do projeto talez tenha reparado #ue ele continha al)uns ar#uios a
mais do #ue os e%plicados no arti)o anterior.
<sses ar#uios formam o conjunto de controllers e iews #ue representam as camadas de re)ras de
ne)2cio e apresenta+*o respectiamente, s*o eles #ue juntamente com o models, formam sua
erdadeira aplica+*o, os ar#uios incluKdos juntamente com o ar#uio compactado s*o criados
automaticamente, #uando oc& cria um projeto usando .end ?ools ou .end :tudio sendo, e
representam o controllers e iews principais e de erro.
Na pr1tica o #ue acontece 7 #ue, #uando al)u7m realiza uma re#uisi+*o ao endere+o we$ onde
est1 sua aplica+*o, ser1 leado ao ar#uio inde%.php, pois todas as chamadas aos diret2rios foram
redefinidas pelo ar#uio .htaccess, o ar#uio inde%.php ir1 direcionar essa aplica+*o para a a+*o
correta do controlador correto, de acordo com os dados encontrados na re#uisi+*o, e se n*o
encontrar #ual#uer um dos dois ir1 direcionar para a a+*o padr*o do controlador padr*o, #ue, caso
nada tenha sido alterado 7 inde%-ction do(nde%'ontroller.
!or e%emplo, uma re#uisi+*o L http://meusitecomzendframework.com.$r ser1 direcionada
a inde%-ction do(nde%'ontroller, j1 uma re#uisi+*o a
http://meusitecomzendframework.com.$r/arti)o ser1 direcionada
ainde%-ction do -rti)o'ontroller 6pois o controller foi definido mas a a+*o n*o8, da mesma forma
uma re#uisi+*o a http://meusitecomzendframework.com.$r/arti)o/editar ser1 direcionado
a editar-ction do -rti)o'ontroller6pois am$os foram definidos8.
/i). 1 - !a)ina (nicial do .end /ramework
Doltando ao projeto criado anteriormente, se oc&s acessarem o caminho referente a esse projeto
no seu nae)ador sem passar nenhum outro parMmetro, poder*o isualizar uma p1)ina do .end
/ramework mostrando #ue tudo est1 funcionando corretamente 6/i). 18, a)ora se
acrescentarem /arti)o ao final da A0@ er*o uma p1)ina de erro dizendo #ue
o -rti)o'ontroller n*o foi encontrado, isso acontece pois todas as re#uisi+,es #ue n*o podem ser
respondidas s*o direcionadas para o <rror'ontroller, #ue cont7m al)umas re)ras de ne)2cios para
e%i$i+*o dos erros ocorridos na p1)ina.
-)ora amos entender como tudo isso acontece, acessando a url do seu projeto sem
nenhum parMmetro, far1 com #ue sua re#uisi+*o seja direcionada para o ar#uio inde%.php, #ue
erificar1 #ue nenhum parMmetro foi passado e conse#Ientemente direcionar1 a re#uisi+*o para
a inde%-ction do (nde%'ontroller, a$rindo o ar#uio(nde%'ontroller.php dentro da
pasta controllers oc& poder1 encontrar dois m7todos, o m7todo init68, #ue inicia o controlador, e
tudo #ue for incluKdo nele, ser1 e%ecutado caso #ual#uer a+*o da#uele controlador seja chamada,
e o m7todo inde%-ction #ue 7 o m7todo #ue estamos $uscando, mas ele est1 azio 6proaelmente
somente com um coment1rio8, ent*o como a#uela p1)ina 7 e%i$ida 6/i). 184 :imples, ao final de
todas as a+,es dos controladores um outro ar#uio, com o mesmo nome da a+*o com a
e%tens*o .phtml, localizada em um diret2rio com o mesmo nome do controlador 6am$os sem os
sufi%os8 dentro do diret2rio../application/iews/scripts 7 chamado automaticamente. <ssa 7 a
iew referente a+*o inde% do controlador inde%, portando estar1 disponKel
em ../application/iews/scripts/inde%/inde%.phtml e nesse ar#uio estar1 contido todo o c2di)o
"?3@ #ue ser1 e%i$ido #uando essa re#uisi+*o for feita.
Al!umas Con"en#es
!or padr*o, no .end /ramework, #uando se utiliza a estrutura de diret2rios recomendada, todos os
controladores deer*o ser ar#uio terminados com o sufi%o 'ontroller localizados dentro do
diret2rio../application/controllers/, )rafados com a primeira letra em mai9sculo, e a palara
'ontroller tam$7m com a primeira letra em mai9sculo, e com a e%tens*o .php, por
e%emplo, (nde%'ontroller.php, -rti)o'ontroller.phpou /aleconosco'ontroller.php e deer*o conter
uma classe com o mesmo nome do ar#uio )rafada da mesma forma #ue e%tenda a
classe .endE'ontrollerE-ction
-s nomes das a+,es dos controladores deer*o terminar com o sufi%o -ction 6com - mai9sculo8 e
serem )rafadas em min9sculo. 'ada a+*o do controlador ir1 chamar um ar#uio com o mesmo
nome da a+*o e e%ten+*o .phtml localizada em um diret2rio com o mesmo nome do controlador
dentro do diret2rio../application/iews/scripts/
No come+o pode parecer um pouco complicado demais, mas todas essas conen+,es ir*o ajudar
muito a or)anizar os ar#uios #uando o projeto come+ar a crescer.
'riando sua !rimeira !a)ina
!ara criar a primeira p1)ina amos alterar o conte9do do ar#uio (nde%'ontroller.php inserindo
dentro do m7todo inde%-ction o se)uinte c2di)o:
p.0lic f.nction inde<Action("
=
6thi/-9)ie8-9tit.lo 7 'Projeto !ello Dorld'(
6thi/-9)ie8-9te<to 7 '!ello Dorld'(
<ssas duas linhas simples est*o armazenando duas ari1eis, tKtulo e te%to com seus alores e
eniando essas ari1eis L iew respectia dessa a+*o. =essa forma iremos tam$7m su$stituir o
conte9do do ar#uio../application/iews/scripts/inde%/inde%.phtml pelo se)uinte:
:EDOCTFP& html PG;LIC B-//DHC//DTD I!TJL C'C//&NB
Bhttp-//888'8H'or+/T2/<htmlCC/DTD/<htmlCC'dtdB9
:html <mln/7Bhttp-//888'8H'or+/CKKK/<htmlB9
:head9
:meta http-e5.i)7Bcontent-typeB
content7Bapplication/<htmlL<ml( char/et7GT%-MB /9
:title9:,php echo 6thi/-9tit.lo(,9:/title9
:/head9
:0ody9
:p9:,php echo 6thi/-9te<to(,9:/p9
:/0ody9
:/html9
0epare #ue 7 um ar#uio N"?3@ simples #ue cont7m apenas dois itens #ue merecem desta#ue,
dentro da ta)JtitleF est1 inserida uma instru+*o para imprimir o alor da ari1el Othis-Ftitulo e
dentro da ta) J$od;F uma outra instru+*o para imprimir o alor da ari1el Othis-Fte%to, essas
foram as duas ari1el criadas na a+*o do controlador e passadas para a iew, sendo assim
#ual#uer ari1el criada da#uela forma no controller pode ser acessada na iew dessa forma.
-)ora acessando noamente o caminho da sua aplica+*o oc& er1 uma p1)ina com o te%to G"ello
BorldH e com o tKtulo "ello Borld. !ode parecer muito tra$alho para pouca coisa, mas dessa forma
oc& separou todas as re)ras de ne)2cio da sua aplica+*o 6c2di)o !"!8 da sua apresenta+*o 6c2di)o
"?3@8, numa aplica+*o maior #ue G"ello BorldH, isso pode diminuir si)nificatiamente o tra$alho
#ue ter1 para encontrar trechos de c2di)o procurados, e realizar as mudan+as #ue precisa na sua
aplica+*o, al7m de dei%ar o c2di)o muito mais limpo e or)anizado.
$e%eren&iado 'inks e Ar(ui"os
-tualizado em 2P/0P/2011
-plica+,es n*o s*o feitas somente de te%to e c2di)os "?3@ e !"! e por isso precisamos armazenar
nossos ar#uios est1ticos em al)um lu)ar #ue possa ser acessado pela aplica+*o de forma natural,
mas como fazemos isso4 Quando criamos nosso ar#uio .htacces no arti)o anterior eu disse #ue
a#uelas linhas de c2di)o direcionariam todas as re#uisi+,es feitas L aplica+*o para o
ar#uio inde%.php, e%ceto se essa re#uisi+*o fosse direcionada para um ar#uio 1lido e e%istente
dentro do diret2rio pu$lic. !ois 7 e%atamente nesse diret2rio #ue deem estar todos os ar#uios
est1ticos #ue oc& ir1 usar na sua aplica+*o 6ima)ens, folhas de estilo, scripts, 1udio, ideo, etc8.
<%istem duas formas para referenciar esses ar#uios
Utili)ando *iew +el,ers
> zend framework possui dois iew helpers #ue est*o disponKeis em todas as iews para au%ili1-lo
#uando tier #ue referenciar ar#uios est1ticos dentro da pasta pu$lic ou outros 'ontrollers e
-ctions para isso $asta utilizar as se)uintes instru+,es no seu ar#uio de iew:
:,php echo 6thi/-90a/eGrl('caminhoparaar5.i)o'<yz'"( ,9
No caso de referenciar um ar#uio est1tico dentro da pasta pu$lic ou
:a href7B:,php echo 6thi/-
9.rl('array('controller'79'inde<'$'action'79'inde<'"$ n.ll$ tr.e'"( ,
9B9LinN:/a9
No caso de uma referencia a um outro controller ou iew.
Utili)ando a Ta! -base.
!ara utilizar a ta) J$aseF do "?3@ $asta inserir a se)uinte instru+*o dentro da sua ta) JheadF
:0a/e href7B:,php echo 6thi/-9/er)erGrl("'6thi/-90a/eGrl("( ,9/B /9
'om isso oc& far1 com #ue automaticamente todos os caminhos relatios do seu c2di)o sejam
relatios a raiz da sua aplica+*o e a partir dai oc& pode referenciar ima)ens ou links da se)uinte
forma:
:im+ /rc7Bzend'jp+B alt7B4end %rame8orNB /9
:a href7Bcontroller/)ie8/B9LinN:/a9
!or #ue Asar J$aseF
Ama das )randes anta)ens de se usar um framework 3D' 7 #ue ele permite a total separa+*o das
re)ras de ne)2cio, apresenta+*o e acesso a dados, e com isso cada profissional, analista de $anco
de dados, front-end deeloper ou pro)ramador, podem cuidar
dos 3odels, Diews e 'ontrollers respectiamente, com isso o front-end deeloper n*o precisa
entender de !"! para #ue possa tra$alhar em conjunto com a e#uipe no desenolimento de uma
aplica+*o, assim como o pro)ramador n*o precisa entender de $anco de dados e o analista n*o
precisa entender de "?3@.
-o utilizar a ta) J$aseF o front-end deeloper respons1el pela marca+*o da aplica+*o n*o precisa
se#uer sa$er #ual framework est1 sendo utilizado j1 #ue ele poder1 tra$alhar com links relatios
simples, sem a necessidade de conhecer a fundo os helpers disponKeis no framework. < caso haja
uma mudan+a no framework utilizado nessa aplica+*o essas mesmas iews podem ser usadas sem
#ue haja necessidade de )randes altera+,es.
-l7m disso nesse caso haer1 somente uma chamada de !"! na p1)ina e n*o uma chamada para
cada link ou ar#uio #ue precisa ser referenciado, melhorando com isso a performance da p1)ina.
-l)uns pro)ramadores criticam o uso da ta) J$aseF defendendo #ue a melhor forma de referenciar
ar#uios ou links seja utilizando os helpers disponKeis no framework, mas minha opini*o 7 #ue o
uso dessa ta) tem todas essas anta)ens j1 citadas, mas no final fica a car)o de cada um escolher
#ual das duas formas utilizar.
Con&luso
>s dois arti)os so$re .end /ramework mostram os primeiros passos para se construir uma aplica+*o
usando o framework, mas oc& pode conse)uir muito mais utilizando-o, com certeza sua aplica+*o
se tornar1 muito mais f1cil e r1pida de ser desenolida e mantida e oc& ainda ter1 L sua m*o
uma asta cole+*o de $i$liotecas para au%ilia-lo nas mais diersas necessidades da sua aplica+*o,
como acesso a dados, autentica+*o e controle de acesso, )era+*o de pdfRs, cone%*o com
aplica+,es e%ternas e muito mais. <spero #ue tenha )ostado dos arti)os e mais poder1 ir em
$ree.
Doc& pode $ai%ar os ar&uivos alterados nesse tutorial, oc& far1 o download de um ar#uio compactado
contendo toda a estrutura de diret2rios do .end /ramework criado no arti)o anterior, juntamente
com as modifica+,es realizadas nesse arti)o. 'aso utilize esses ar#uios ainda ser1 necess1rio
copiar a pasta .end para dentro do diret2rio li$rar; #ue n*o foi incluKda com esse ar#uio.
Nos 9ltimos arti)os t7cnicos escrei so$re como montar a estrutura de um projetos !om Zend
Framework e como !riar sua primeira apli!a'(o usando a estrutura criada, mas nessa primeira
aplica+*o n*o fazKamos uso de um $anco de dados, o #ue na maioria dos casos 7 diferente. 5oa
parte das aplica+,es desenolidas para a we$ fazem uso de al)um tipo de armazenamento de
dados, seja eles utilizando $ancos de dados em te%to ou $anco de dados no modelo o$jeto-
relacional. =essa forma nesse arti)o ou mostrar como 7 possKel confi)urar a cone%*o a esses
$ancos de dados utilizando .end /ramework.
'omo #uase tudo no .end /ramework e%istem diersas formas de se confi)urar a cone%*o com o
$anco de dado na sua aplica+*o, ou tentar mostrar al)umas delas dizendo #uais s*o os pontos
positios e ne)atios de cada uma:
Al!umas Premissas /e&ess0rias
:e)undo a documenta+*o oficial do /ramework os se)uintes $ancos de dados s*o suportados de
forma natia: 3aria=5, 3;:#l, (35 =52, 3icrosoft :Q@ :erer, >racle, !ost)re:Q@, :Q@ite, /ire$ird.
S uma lista $em e%tensa e com certeza co$re a imensa maioria das aplica+,es we$ hoje, mas caso
seu $anco de dados n*o esteja na lista isso n*o si)nifica #ue oc& n*o poder1 utiliz1-lo, oc& ainda
pode criar seu pr2prio adaptador, mas esse seria um t2pico $astante aan+ado #ue n*o 7 o o$jetio
desse arti)o.
!ortanto, para #ue oc& consi)a realizar a cone%*o #ue irei mostrar atra7s desse arti)o estou
supondo #ue oc& j1 tenha confi)urado um desses e j1 tenha criado um $anco de dados para uso
nessa aplica+*o. :e ainda n*o o fez ou n*o sa$e como fazer su)iro #ue consulte a documenta+*o
especKfica do seu :T5= pois n*o seria possKel nesse arti)o apenas mostrar como confi)urar cada
um desses indiidualmente 6nem eu mesmo sa$eria como fazer em todos eles8.
Ini&iali)ao Indi"idual do 1an&o de Dados
:e sua aplica+*o usa pouco o $anco de dados e somente em al)umas partes dela essa talez seja
uma solu+*o ade#uada para oc& nesse momento, pois permite #ue oc& possa inicializar o $anco
de dados, #uando e somente #uando oc& necessitar dessa cone%*o, para tanto oc& dee apenas
usar a se)uinte instru+*o no seu 'ontroller:
6d0 7 ne8 4endD0AdapterPdoJy/5l(array(
'ho/t' 79 'localho/t'$
'./ername' 79 './.Orio'$
'pa//8ord' 79 '/enha'$
'd0name' 79 'nomedo0ancodedado/'
""(
Damos a e%plica+*o, a primeira linha dessa instru+*o inicializa a classe do adaptador referente ao
$anco de dados especKfico #ue oc& est1 usando 6uma lista completa de todos os adaptadores pode
ser encontrada no final da %o!umenta'(o de )an!o de %ados do Zend Framework8, oc& dee portanto
su$stituir pela classe correta do adaptador do seu $anco de dados.
'omo parMmetro dessa inicializa+*o s*o passados os dados de cone%*o com o $anco de dados, #ue
podem ariar um pouco de um :T5= para outro mas s*o $asicamente esses:
"ost: (p, 'aminho ou A0@ do seu seridor do seu :T5=
Asername: Nome de Asu1rio para cone%*o com o :T5=
!assword: :ua senha para cone%*o com o :T5=
=5Name: Nome do $anco de dados especKfico
- partir dai $asta oc& e%ecutar sua instru+*o :Q@ atra7s da classe criada e armazenada na
ari1el Od$ como no e%emplo a se)uir:
6/5l 7 '1&L&CT 3 %2OJ JyTa0le D!&2& ta0leId 7 P'(
6re/.lt 7 6d0-9fetchAll(6/5l"(
'one%*o Atilizando .endE=$::factor;68
- fun+*o est1tica factor; da classe .endE=$ inicializa a classe do $anco de dados automaticamente
atra7s da.endE@oader::load'lass68 da classe e retorna uma instMncia dessa classe para usar
factor; tudo #ue oc& tem #ue fazer e su$stituir a instru+*o de cone%*o pela se)uinte:
6d0 7 4endD0--factory('PdoJy/5l'$ array(
'ho/t' 79 'localho/t'$
'./ername' 79 './.ario'$
'pa//8ord' 79 '/enha'$
'd0name' 79 'nomedo0ancodedado/'
""(
'omo disse anteriormente essas duas formas de realizar a cone%*o s*o muito 9teis se sua aplica+*o
se conectar pou#uKssimas ezes com o $anco de dados, pois oc& ter1 #ue inicializ1-lo toda ez
#ue for us1-lo e ainda ter1 #ue armazenar os dados de cone%*o em cada um dos 'ontrollers #ue
forem realizar a cone%*o, caso um dia esses dados mudem oc& ter1 um tra$alho imenso para
su$stituir cada um deles.
Cone2o Indi"idual Utili)ando um Ar(ui"o de Con%i!urao
!ara resoler o pro$lema anteriormente apresentado oc& pode armazenar as informa+,es de
cone%*o em um ar#uio de confi)ura+*o e $uscar essas informa+,es desse ar#uio #uando for
realizar a cone%*o, dessa forma se os dados de cone%*o mudarem oc& ter1 #ue atualiz1-los em
somente um ar#uio.
:e oc& est1 usando a estrutura apresentada nos arti)os anterior, recomendada pela .end ou
realizou a cria+*o do seu projeto usando .end ?ool, oc& j1 tem um ar#uio de confi)ura+*o na sua
aplica+*o, #ue est1 localizado dentro de application/confi)s/application.ini para esse arti)o
iremos usar esse ar#uio mesmo, mas a medida #ue sua aplica+*o for crescendo oc& pode #uerer
or)anizar melhor as confi)ura+,es em diferentes ar#uios, oc& poder1 fazer isso sem pro$lema
al)um.
-dicione as se)uintes linhas ao seu ar#uio 6no lu)ar correspondente ao seridor #ue estier
usando8 e su$stitua os dados pelos dados de cone%*o referentes ao seu :T5=:
d0'adapter 7 PDOJF1QL
d0'param/'ho/t 7 localho/t
d0'param/'./ername 7 ./.ario
d0'param/'pa//8ord 7 /enha
d0'param/'d0name 7 nomedo0ancodedado/
-)ora o #ue oc& tem #ue fazer #uando for usar o $anco de dados e su$stituir o c2di)o usado nos
e%emplos anteriores pelo se)uinte:
6confi+ 7 ne8 4endConfi+Ini('''/application/confi+//application'ini'"(
6d0 7 4endD0--factory(6confi+-9d0"(
=essa forma oc& estar1 passando como parMmetro para o m7todo est1tico factor;68 os dados
contidos no seu ar#uio de confi)ura+*o.
Cone2o Atra"3s da Classe de 1ootstra,
Nas formas anteriores oc& tinha #ue instanciar o $anco de dados toda ez #ue ele fosse ser usado,
o #ue pode ser $om #uando a aplica+*o se utiliza pouco de cone%,es a $ancos de dados, pois eita
#ue sua aplica+*o seja so$recarre)ada com cone%,es desnecess1rias ao $anco, mas #uando a
maioria ou a totalidade da aplica+*o se utiliza de cone%,es ao $anco de dados o ideal 7 #ue essa
cone%*o seja inicializada juntamente com sua aplica+*o e permane+a atia durante toda ela, e isso
pode ser feito atra7s do ar#uio $ootstrap.phplocalizado na raiz do diret2rio application
!ara isso $asta criar o se)uinte m7todo nessa classe:
protected f.nction initConnection("
=
6confi+ 7 ne8
4endConfi+Ini('''/application/confi+//application'ini'$
APPLICATION&N*"(
try=
6d0 7 4endD0--factory(6confi+-9d0"(
// 2e+i/tra o 0anco de dado/
6re+i/try 7 4end2e+i/try--+etIn/tance("(
6re+i/try-9/et('d0'$ 6d0"(
4endD0Ta0le--/etDefa.ltAdapter(6d0"(
>catch(4endD0&<ception 6e"=
echo BNRo foi po//S)el realizar a cone<Ro com o 0anco de
dado/'B(
e<it(
>
>
?odo o m7todo protected cujo nome inicia com GEinitH da sua classe $ootstrap 7 inicializado
juntamente com sua aplica+*o, dessa forma, esse m7todo ser1 automaticamente inicializado junto
com sua aplica+*o, realizar1 a cone%*o com o $anco de dados atra7s do m7todo
est1tico .endE=$::factor;68 e em se)uida re)istrar1 esse m7todo atra7s de .endE0e)istr; #uando
oc& for utilizar o $anco de dados $asta recuper1-lo usando a se)uinte instru+*o:
6re+i/try 7 4end2e+i/try--+etIn/tance("(
6d0 7 6re+i/try-9+et('d0'"(
> m7todo Einit'onnection tam$7m re)istra o o$jeto do $anco de dados como adaptador padr*o de
$anco de dados para a aplica+*o, dessa forma os models #ue forem criados nessa aplica+*o far*o
uso por padr*o desse $anco de dados.
Con&luso
'omo dito anteriormente e%istem diersas formas de se realizar a cone%*o com o $anco de dados
no .end /ramework, eu sempre procuro mostrar essas diersas formas para #ue cada um possa
escolher a #ue melhor se adapta a sua aplica+*o, mas se oc& planeja um crescimento para sua
aplica+*o e o uso de models nela, recomendo #ue fa+a uso da 9ltima maneira descrita, pois j1
re)istra seu $anco de dados como padr*o e mantem as informa+,es de cone%*o em um ar#uio de
confi)ura+*o separado para #ue caso al)o tenha #ue ser alterado seja feito alterando somente um
ar#uio. > uso de models porem 7 um assunto para um pr2%imo arti)o.
/ormul1rio s*o a principal portal de entrada de dados do usu1rio em um site, 7 atra7s deles #ue o
usu1rio insere suas informa+,es, realiza $uscas, cadastros e muitas outras atiidades em um site ou
sistema, por isso 7 impossKel pensar em uma aplica+*o para a we$ sem pensar na possi$ilidade de
essa aplica+*o possuir um formul1rio. > .end /ramework possui uma asta $i$lioteca para
utiliza+*o de formul1rios, incluindo marca+*o filtros e alida+*o, muitas dessas funcionalidades
facilitam $astante o desenolimento de uma aplica+*o e 7 dessas funcionalidades #ue esse arti)o
ir1 tratar.
-ntes de iniciar esse arti)o por7m 7 importante #ue oc& j1 esteja familiarizado com os conceitos
do framework, caso oc& n*o tenha esse conhecimento $1sico su)iro #ue inicie sua leitura pelos
arti)os Criando Um Projeto Com Zend Framework e *ais +ue #ello ,orld !om Zend Framework j1
pu$licados nesse $lo), outros arti)os so$re o tema tam$7m podem ser encontrados na se+*o
so$re Zend Framework.
Criando um Formul0rio
Am formul1rio com .end /ramework 7 $asicamente uma instMncia da classe .endE/orm, portanto
para criar um $anco de dados com .end $asta criar uma instMncia dessa classe, isso pode ser feito
diretamente em seu 'ontroller, da se)uinte forma:
6form 7 ne8 4end%orm(
'om essa instru+*o uma noa instMncia da classe .endE/orm 7 criada e armazenada na
ari1el Oform, a partir dai oc& j1 pode realizar as confi)ura+,es necess1rias no seu formul1rio ou
adicionar elementos a ele, como eremos a se)uir.
Con%i!ura#es do Formul0rio
Am formul1rio dee possuir al)umas confi)ura+,es $1sicas para #ue seu funcionamento seja
efetio al)umas dessas confi)ura+,es dizem respeito ao m7todo usado pelo formul1rio para eniar
os dados e a o destino da a+*o dos formul1rios, essas confi)ura+,es podem ser realizadas atra7s
da se)uintes instru+,es:
6form-9/etJethod('po/t'"(
6form-9/etAction('mod.le/controller/action'"(
-l7m disso outros atri$utos podem ser adicionados ao formul1rio da se)uinte forma:
6form-9/etAttri0('id'$ 'lo+in'"(
Adi&ionando Elementos
'omo #uase tudo no .end /ramework 7 possKel realizar a cria+*o de um elemento de formul1rio e
incluK-lo no mesmo de al)umas formas diferentes.
Criando os Elementos e Inserindo4os Posteriormente no Formul0rio
> .end /ramework possui diersas classes para o elementos de um formul1rio "?3@, al7m de
al)umas outras classes para elementos au%iliares como 'aptcha. !ara realizar a cria+*o de um
elemento de formul1rio $asta instMnciar a classe correspondente ao elemento desejado da se)uinte
forma:
Oelemento U new .endE/ormE<lementE?e%t6Vname<lementoW8X
- instru+*o acima est1 realizando a cria+*o de um Jinput t;peUHte%tHF e armazenando o mesmo na
ari1el Oelemento, o construtor da classe rece$e como parMmetro o atri$uto name desse
elemento no formul1rio "?3@. -l7m do elemento do tipo te%to al)umas dos elementos mais
comuns s*o representados pelas classes .endE/ormE<lementE!assword,
.endE/ormE<lementE?e%tarea, .endE/ormE<lementE'heck$o%, .endE/ormE<lementE:elect,
dentre outras, para uma lista completa da classes oc& deer1 consultar a Se'(o de Formul$rios no
3anual do Zend Framework.
-)ora oc& ainda pode adicionar um elemento por ez no formul1rio, ou criar diersos elementos e
adicion1-los de uma 9nica ez no formul1rio, am$as as formas s*o e%pressas a$ai%o
respectiamente:
6form-9add&lement(6elemento"(
6form-9add&lement/( array(6elementoC$ 6elementoP$ 6elementoH""(
(ncluindo Noos <lementos =iretamente no /ormul1rio
!ara criar noos elementos diretamente no formul1rio oc& dee realizar a se)uinte instru+*o:
6form-9add&lement('Te<t'$ 'nome&lemento'"(
> 37todo add<lement pode rece$er como parMmetro tanto um o$jeto do tipo .endE/ormE<lement
6como no e%emplo anterior8 como uma strin) #ue se refira ao tipo de elemento #ue se deseja
incluir 6a 9ltima parte do nome da classe8, nesse o se)undo parMmetro desse m7todo ser1 o nome
do elemento a ser criado e ainda 7 possKel passar um terceiro parMmetro com um arra; de op+,es
para o elemento.
Filtros e *alidadores em um Formul0rio
N*o 7 muito difKcil confundir filtros com alidadores no .end /ramework, mas a diferen+a deles 7
$em simples, um alidador ir1 erificar se o alor em #uest*o est1 de acordo com al)uma
e%i)&ncia e ir1 retornar true caso esteja ou false caso n*o esteja, j1 o se)undo ir1 tentar filtrar o
alor em #uest*o com $ase em al)uma e%i)&ncia, como por e%emplo retirar caracteres de espa+o
no inKcio e final do alor e ent*o retornar1 o alor filtrado ou false caso n*o seja possKel realizar a
a+*o pretendida.
=e modo )eral o alidador n*o altera o alor em #uest*o apenas erifica se est1 ou n*o de acordo
com as e%i)&ncia j1 o filtro tenta alterar o alor para #ue esse fi#ue de acordo com as e%i)&ncias.
:a$endo disso amos a)ora er como inserir alidadores e filtros nos elementos do formul1rio.
Adi&ionando *alidadores
-dicionar alidadores no seu formul1rio 7 muito simples, $asta realizar a se)uinte instru+*o:
6elemento-9add*alidator('Not&mpty'"(
No e%emplo acima estamos inserindo um alidador #ue erifica se Oelemento criado anteriormente
n*o est1 azio. =iersos outros alidadores s*o encontrados juntamente com o .end /ramework,
uma lista completa deles pode ser encontrada na :e+*o de Dalidadores do manual.
Adi&ionando Filtros
'om o filtro oc& dee proceder de forma muito parecida atra7s da se)uinte instru+*o:
6elemento-9add%ilter('1trin+Trim'"
> <%emplo acima retira caracteres de espa+o do inicio e do final do alor passado pelo campo.
=iersos outros filtros podem ser encontrados juntamente com o .end /ramework, uma lista
completa deles pode ser encontrada na :e+*o de /iltros do manual.
Utili)ando Uma Classe (ue E2tenda Zend5Form
-l)umas ezes utilizar o formul1rio diretamente no seu controller pode torn1-lo e%tenso demais e
difKcil de ser mantido, outras ezes um mesmo formul1rio pode ser usado em diferentes situa+,es
dessa forma tam$7m 7 possKel utilizar formul1rios com .end /ramework criando um classe #ue
estenda a classe .endE/orm da se)uinte forma:
cla// Application%ormLo+in e<tend/ 4end%orm
=
p.0lic f.nction init("
=
//In/tr.TUe/ do 1e. %orm.lOrio
>
>
No e%emplo criei um formul1rio de lo)in e portanto se)uindo a conen+*o de nomenclatura do
.end /ramework a classe dee se chamar -pplicationE/ormE@o)in e estar localizada no
diret2rio application/formem um ar#uio de nome @o)in.php. 'aso seu formul1rio seja usado em
outra situa+*o os de classe, e ar#uio podem ser alterados para se ade#uar ao uso, como por
e%emplo .endE/ormE'ontato.
<ssa classe dee estender a classe .endE/orm e no seu m7todo init68 oc& poder1 criar o seu
formul1rio da mesma forma #ue foi feito diretamente no controller, n*o es#uecendo apenas #ue
oc& deer1 usar Othis para referenciar a classe .endE/orm ao in7s da ari1el Oform na #ual ela
haia sido armazenada anteriormente pois essa classe est1 estendendo .endE/orm.
'aso realize a cria+*o do seu formul1rio dessa maneira deer1 proceder da se)uinte forma no
seu controller:
6form 7 ne8 Application%ormLo+in(
> /ormul1rio 'ompleto
=epois de criado o formul1rio, e inseridos nele seus elementos juntamente com seus respectios
alidadores e filtros e hora de juntar todas as informa+,es para #ue o formul1rio funcione de
erdade, para isso ou usar como e%emplo um formul1rio de lo)in com campos para lo)in e senha
al7m do $ot*o de su$mit.
6 Ar(ui"o do Formul0rio
No e%emplo proposto o ar#uio do formul1rio ficar1 da se)uinte forma:
cla// Application%ormLo+in e<tend/ 4end%orm
=
p.0lic f.nction init("
=
6lo+in 7 ne8 4end%orm&lementTe<t('./erLo+in'"(
6lo+in-9/etLa0el('Lo+in do G/.ario'"
-9/et2e5.ired(tr.e"
-9add%ilter('1tripTa+/'"
-9add%ilter('1trin+Trim'"(
6/enha 7 ne8 4end%orm&lementPa//8ord('pa//Lo+in'"(
6/enha-9/etLa0el('1enha do G/.ario'"
-9/et2e5.ired(tr.e"
-9add%ilter('1tripTa+/'"
-9add%ilter('1trin+Trim'"(
6/.0mit 7 ne8 4end%orm&lement1.0mit('&ntrar'"(
6thi/-9add&lement/(array(6lo+in$ 6/enha$ 6/.0mit""(
>
>
/oram criados os campos de lo)in e senha e senha, am$os de preenchimento o$ri)at2rio e com um
filtro para remoer os caracteres de espa+o do inKcio e do final da strin), al7m do
filtro :trip?a)s #ue remoe #ual#uer marca+*o do te%to, j1 #ue o #ue #ueremos rece$er como
resposta s*o somente dois alores em te%to simples. -l7m disso usei ainda o m7todo set@a$el68 dos
o$jetos para adicionar e confi)urar um alor para o elementoJla$elF do formul1rio #ue se refere a
cada um dos campos.
6 Controller
Doc& poder1 usar o mesmo controller #ue e%i$e o formul1rio para rece$er tam$7m os dados desse
formul1rio, para isto $asta #ue oc& erifi#ue se os dados n*o foram eniados e nesse caso e%i$a o
formul1rio ou se eles j1 forma eniados e nesse caso realize as a+,es necess1rias com esses alores
da se)uinte forma:
6form 7 ne8 Application%ormLo+in("(
6thi/-9)ie8-9form 7 6form(
if(6thi/-9+et2e5.e/t("-9i/Po/t(" and 6form-9i/*alid(6PO1T""=
6)al.e/ 7 6thi/-9)ie8-9form-9+et*al.e/("(
//2ealize a/ ATUe/ com o/ *alore/ 2ece0ido/
>
Nesse caso foi criada uma instMncia da classe do formul1rio criada anteriormente e armazenada na
ari1elOform #ue foi lo)o em se)uida passada para a iew, posteriormente 7 erificado se o
formul1rio j1 foi eniado e se os dados passados s*o 1lidos. 'aso isso seja erdadeiro chamamos o
m7todo )etDalues68 do o$jeto do formul1rio, esse m7todo retornar1 um arra; tendo como chae os
nomes dos elementos do formul1rio contendo os alores eniados. 'aso o formul1rio ainda n*o
tenha sido eniado ou os dados n*o sejam 1lidos essa parte do c2di)o ser1 i)norada passando
diretamente para o final da a+*o e conse#Iente chamada L iew.
A *iew
< na sua iew, no local onde o formul1rio dee ser renderizado $asta apenas adicionar a se)uinte
instru+*o:
:,php echo 6thi/-9form( ,9
'onclus*o
- 'lasse .endE/orm permite #ue oc& )erencie todas as fun+,es do seu formul1rio, no come+o o
seu uso pode parecer um pouco complicado assim como o inKcio com o modelo 3D', mas lo)o
poder1 perce$er #ue o n9mero de anta)ens no seu uso 7 muito mair #ue o pouco de tra$alho #ue
oc& ter1 no come+o para aprender como usa-lo e criar seus primeiros formul1rios.
Apload de -r#uios 'om .end /ramework
<m muitos projeto 7 necess1rio #ue seu usu1rio ou isitante realizem o enio de al)um ar#uio
para o seridor do site, o uso mais comum atualmente desse recurso 7 o enio de uma ima)em para
ser usada como ima)em de usu1rio, mas em muitas outras ocasi,es pode ser necess1rio fazer o
upload de ar#uios atra7s de sua aplica+*o. Nesse arti)o pretendo mostrar como fazer o upload
de ar#uios diretamente de um /ormul1rio do .end /ramework como tam$7m utilizando a classe
.endE/ile utilizada para transfer&ncia de ar#uios.
U,load de Ar(ui"os Diretamente do Formul0rio7
No arti)o so$re Formul$rios em Zend Framework eu j1 descrei o funcionamento de um formul1rio
utilizando a classe .endE/orm, portanto n*o ou detalhar muito o funcionamento nesse arti)o, se
oc& sentir #ue precisa de al)uma informa+*o preliminar su)iro #ue realize a leitura do ar#uio
anteriormente.
:a$endo do funcionamento de um formul1rio com .endE/orm o tra$alho necess1rio para o upload
do ar#uio se torna praticamente ine%istente, tudo o #ue oc& precisar1 fazer ser1 adicionar a esse
formul1rio um campo do tipo file da se)uinte forma:
6element 7 ne8 4end%orm&lement%ile('fileGpload'"(
6element-9/etLa0el('Ar5.i)o'"
-9add*alidator('&<ten/ion'$ fal/e$ array('jp+'$ 'pn+'$ '+if'""
-9add*alidator('1ize'$ fal/e$ CAPVAA"
-9/etDe/tination(.pload''"(
Nesse caso foi criado um campo de formul1rio do tipo GfileH com dois alidadores, um para #ue a
e%tens*o do ar#uio passado seja somente uma das tr&s op+,es passadas como parMmetro e outro
erificando #ue o tamanho do ar#uio n*o ultrapasse 100k$. -l7m disso 7 chamado o
m7todo set=estination68 do o$jeto informando em #ual diret2rio o ar#uio eniado dee ser
armazenado.
/eito isso #uando o m7todo )etDalues68 do formul1rio for chamado no seu controller o ar#uio ser1
automaticamente eniado para o diret2rio em #uest*o.
U,load de Ar(ui"os &om Zend5File
0ealizar o Apload com .endE/ile 7 um pouco mais comple%o #ue diretamente com o formul1rio,
mas permite #ue a ori)em do ar#uio eniado seja outra #ue n*o um formul1rio "?3@, nesse
e%emplo amos continuar usando um formul1rio "?3@ mas oc& pode adaptar o e%emplo para as
suas necessidades.
!recisaremos apenas de uma pe#uena modifica+*o no c2di)o anterior do formul1rio #ue ficar1 da
se)uinte forma:
6element 7 ne8 4end%orm&lement%ile('fileGpload'"(
6element-9/etLa0el('Ar5.i)o'"
-9add*alidator('&<ten/ion'$ fal/e$ array('jp+'$ 'pn+'$ '+if'""
-9add*alidator('1ize'$ fal/e$ CAPVAA"(
(
Nesse caso estamos remoendo o destino do ar#uio do formul1rio pois se manti7ssemos essa
informa+*o o ar#uio seria duplamente eniado para o destino, uma ez pelo formul1rio e outra
pela classe .endE/ile. Y1 seu controller ficar1 da se)uinte forma:
if(6thi/-9+et2e5.e/t("-9i/Po/t(" and 6form-9i/*alid(6PO1T""=
6ima+eAdapter 7 ne8 4end%ileTran/ferAdapter!ttp("(
6ima+eAdapter-9/etDe/tination('.pload'"(
if(i/.ploadedfile(6%IL&1?'fileGpload'@?'tmpname'@""=
if (E6ima+eAdapter-9recei)e('fileGpload'""=
6me//a+e/ 7 6ima+eAdapter-
9+etJe//a+e/?'fileGpload'@
//A Ima+em NRo %oi 2ece0ida Corretamente
>el/e=
//Ar5.i)o &n)iado Com 1.ce//o
//2ealize A/ ATUe/ Nece//Oria/ Com O/ Dado/
6filename 7 6ima+eAdapter-
9+et%ileName('fileGpload'"
>
>el/e=
//O Ar5.i)o NRo %oi &n)iado Corretamente
>
>
No e%emplo acima erificamos se o formul1rio foi eniado e se seus alores s*o 1lidos em se)uida
criamos uma instMncia da classe .endE/ile e armazenamos essa instMncia dentro
da ari1el Oima)e-dapter a partir dessa instMncia informamos o diret2rio de destino do ar#uio a
ser eniado, em se)uida erificamos se a ima)em foi realmente eniada e se est1 disponKel como
ar#uio tempor1rio, se isso for erdadeiro realizamos a transfer&ncia do ar#uio para o diret2rio
correto atra7s do m7todo receie68 do o$jeto da classe .endE/ile, esse m7todo ir1 retornar true
caso a transfer&ncia seja $em sucedida ou false caso n*o seja. :e ela for $em sucedida oc&
poder1 recuperar o caminho do ar#uio correto atra7s do m7todo )et/ileName68X e realizar as
deidas a+,es com essa informa+*o, caso n*o seja $em sucedida as mensa)ens de erro poder*o ser
recuperadas pelo m7todo )et3essa)es e oc& poder1 ent*o e%i$ir essa mensa)em de erro.
Con&luso
:e for realizar um upload simples de ar#uio atra7s de um formul1rio, su)iro #ue utilize a
primeira das forma apresentadas pois como foi isto 7 $em mais simples #ue a se)unda, por7m se
essa transfer&ncia e%i)ir confi)ura+,es mais aan+adas ou for uma transfer&ncia de um ar#uio #ue
n*o se ori)ine de um formul1rio "?3@ oc& poder1 usar a se)unda op+*o. 'omo sempre o .end
/ramework apresenta diersas maneiras de se realizar a mesma coisa, $asta oc& escolher #ual
dela se adapta melhor as suas necessidades.
0elacionamento de ?a$elas com .endE=$
-nteriormente escrei a#ui no $lo) so$re como Con-igurar um )an!o de %ados !om Zend
Framework eTra.alhar !om *odels no Zend Framework, por7m em muitos casos al7m de acessar as
entradas no $anco de dados de uma 9nica ta$ela n2s tam$7m precisamos tra$alhar com os
relacionamentos entre as ta$elas no $anco de dados, para isso o ./ possui uma s7rie de recursos
#ue au%iliam no tra$alho com ta$elas relacionadas no $anco de dados e 7 so$re esses recursos #ue
pretendo escreer nesse arti)o.
Con%i!urando os odels
3odelo do 5anco de =ados
-ntes de come+ar a tra$alhar com o relacionamento de ta$elas com .end /ramework 7 preciso
realizar al)umas confi)ura+,es nos 3odels referentes as ta$elas em #uest*o, nesse arti)o ou usar
como e%emplo o $anco de dados representado na ima)em ao lado. !ara confi)urar os
relacionamentos desse $anco de dados oc& dee adicionar al)umas ari1eis do tipo protected ao
seu model, ficando eles da se)uinte forma:
cla// ApplicationJodel/G/.ario e<tend/ 4endD0Ta0leA0/tract
=
protected 6name 7 'G/.ario'(
protected 6primary 7 'idG/.ario'(
protected 6dependentTa0le/ 7 array(BComentarioB"(
"(
class -pplicationE3odelsE-rti)o e%tends .endE=$E?a$leE-$stract
=
protected 6name 7 'Arti+o'(
protected 6primary 7 'idArti+o'(
protected 6dependentTa0le/ 7 array(BComentarioB"(
"(
class -pplicationE3odelsE'omentario e%tends .endE=$E?a$leE-$stract
=
protected 6name 7 'Comentario'(
protected 6primary 7 'idComentario'(
protected 6referenceJap 7 array(
BG/.arioB 79 array(
Bcol.mn/B 79 array(BidG/.arioB"$
BrefTa0leCla//B 79 BApplicationJodel/G/.arioB$
BrefCol.mn/B 79 array(BidG/.arioB"$
"$
BArti+oB 79 array(
Bcol.mn/B 79 array(BidArti+oB"$
BrefTa0leCla//B 79 BApplicationJodel/Arti+oB$
BrefCol.mn/B 79 array(BidArti+oB"$
"$
"(
"(
-)ora amos as e%plica+,es, nesse caso foram criados tr&s ar#uios models, um para cada uma das
ta$elas no $anco de dados modelo, as duas primeiras classes s*o referentes as ta$elas de usu1rio e
de arti)os, e nelas foi inserida uma ari1el prote)ida OEdependent?a$les, #ue rece$e como alor
um arra; com o nome de todas as outras ta$elas com as #uais elas se relacionam, nesse caso
am$as se relacionam somente com a ta$ela de coment1rio.
Y1 na ta$ela de coment1rio, as coisas ficam um pouco diferentes, a ta$ela de coment1rios est1 no
lado GNH do relacionamento e 7 nessa ta$ela #ue oc& deer1 adicionar as informa+,es referentes
as colunas #ue se relacionam em cada ta$ela do $anco, isso 7 feito atra7s da
ari1el OEreference3ap, #ue contem noamente um arra; #ue tem como chae os nomes das
ta$elas com as #uais essa se relaciona e como alor um outroarra; com os dados do
relacionamento.
<sse se)undo arra; dee conter al)uns elementos chae, sendo columns um outro arra; com as
colunas #ue referenciam a outra ta$ela na de coment1rio, ref?a$le'lass o nome da classe model da
ta$ela #ue se relaciona com o model de coment1rio e ref'olumns o nome das colunas da ta$ela de
coment1rio #ue completam o relacionamento. No come+o pode parecer um pouco confuso
confi)urar todas essas refer&ncias em arra;s multidimensionais como 7 feito, mas conforme oc&
for se familiarizando melhor com as nomenclaturas isso se torna cada ez mais f1cil.
$ela&ionamento Um Para uitos
=epois de feita toda a confi)ura+*o necess1ria nos models che)amos a parte em #ue aproeitamos
o m1%imo do tra$alho realizado, a hora em #ue $uscamos os elementos relacionados as linhas da
nossa ta$ela, no caso de um relacionamento um para muitos o .end /ramework possui o
m7todo find=ependent0owset68 #ue pode ser utilizado das se)uintes formas:
6arti+oJodel 7 ne8 ApplicationJodel/Arti+o("(
6arti+o 7 6arti+oJodel-9fetch2o8('idArti+o 7 C'"(
6comentario/ 7 6arti+o-
9findDependent2o8/et('ApplicationJodel/Comentario'"(
6./.arioJodel 7 ne8 ApplicationJodel/G/.ario("(
6./.ario 7 6./.arioJodel-9fetch2o8('idG/.ario 7 C'"(
6comentario/ 7 6./.ario-
9findDependent2o8/et('ApplicationJodel/Comentario'"(
No primeiro e%emplo nos $uscamos todos os coment1rios de um determinado arti)o atra7s do
m7todofind=ependent0owset68 e no se)undo todos os coment1rios realizados por um usu1rio
atra7s do mesmo m7todo, como podemos er o tra$alho e%tra para confi)urar os modelos e
totalmente recompensado com a facilidade de utiliza+*o desse m7todo.
$ela&ionamento uitos Para uitos
>utro cen1rio possKel seria o caso de precisarmos $uscar todos os usu1rios #ue realizaram
coment1rios em um determinado arti)o, dessa forma estarKamos fazendo uso do relacionamento N-
N formado entre as ta$elas de usu1rios e arti)os e intermediado pela ta$ela de coment1rio,
tra$alhar com esse cen1rio 7 #uase t*o f1cil #uanto com o anterior, para isso o .end /ramework
possui o m7todo find3an;?o3an;0owset68 #ue pode ser utilizado da se)uinte forma:
6arti+oJodel 7 ne8 ApplicationJodel/Arti+o("(
6arti+o 7 6arti+oJodel-9fetch2o8('idArti+o 7 C'"(
6./.ario/ 7 6arti+o-9findJanyToJany2o8/et('ApplicationJodel/G/.ario'$
'ApplicationJodel/Comentario'"(
> m7todo citado rece$e como parMmetros os nomes da ta$ela #ue realizam o relacionamento
conforme confi)urado no model.
Con&luso
'onfi)urar os models para utiliza+*o dos m7todos de relacionamento de ta$elas pode ser um pouco
tra$alhoso e confuso no come+o, mas com a pratica e a familiariza+*o com os ar)umentos
necess1rio essa pratica se torna corri#ueira e simples, mas os $enefKcios da facilidade de uso dos
m7todos em #uest*o est*o s*o superiores a #ual#uer dificuldade inicial #ue oc& possa ter ao
utilizar essa funcionalidade do framework.
<niando <-mail com .endE3ail
<niar e-mail com !"! 7 uma das tarefas mais f1ceis da lin)ua)em, $asta oc& ter um seridor de
e-mail corretamente confi)urado no seu local de hospeda)em e passar os parMmetros corretos para
a fun+*o mail68, ent*o para #ue utilizar um framework para au%iliar em uma tarefa tanta f1cil
#uanto essa4 :imples, pois o .end /ramework facilita ainda mais o #ue j1 era f1cil e ainda
contempla o pro)ramador com uma s7rie de noas funcionalidades para essa a+*o.
En"iando um E4mail Sim,les
!ara eniar um e-mail simples usando .endE3ail tudo #ue 7 necess1rio fazer 7 criar uma instMncia
da classe .endE3ail, no e%emplo a$ai%o, armazenada na ari1el Omail e em se)uida utilizar os
m7todos dessa classe para confi)urar o e-mail #ue ser1 eniado.
6mail 7 ne8 4endJail("(
6mail-9/et;odyTe<t('Te<to do &-mail'"(
6mail-9/et1.0ject('A//.nto do Contato'"(
6mail-9/et%rom('remetenteWremetente'com'0r'$ '2emetente'"(
6mail-9addTo('de/tinatarioWde/tinatario'com'0r'$ 'De/tinatOrio'"(
6mail-9/end("(
> m7todo set5od;?e%t68 rece$e como parMmetro o te%to do e-mail 6em te%to puro8, em se)uida s*o
passados os alores do -ssunto, 0emetente e =estinat1rio para os m7todos posteriores no e%emplo
acima, os dois 9ltimos podem rece$er somente um parMmetro sendo o endere+o de e-mail em
#uest*o, ou rece$er tam$7m um se)undo parMmetro com o nome da pessoa em #uest*o. !or fim o
m7todo send68 7 chamado para realizar o enio do e-mail #ue foi confi)urado.
Utili)ando o Proto&olo STP
> protocolo padr*o do .endE3ail 7 praticamente uma e%tens*o da fun+*o mail68, porem ainda 7
possKel eniar e-mail utilizando o protocolo :3?!, caso as confi)ura+,es de seridor :3?! estejam
deidamente confi)uradas no seu seridor tudo #ue oc& precisa fazer 7 alterar o protocolo padr*o
da se)uinte forma:
6protocolo 7 ne8 4endJailTran/port1mtp('mail'/er)idor'com'"(
4endJail--/etDefa.ltTran/port(6protocolo"(
> #ue foi feito foi criar uma noa instMncia da classe .endE3ailE?ransportE:mtp passando como
parMmetro para seu construtor o endere+o do seridor 6#ue por padr*o 7 G12Z.0.0.1[8 e em se)uida
passar essa instMncia da classe para o m7todo est1tico set=efault?ransport68 da classe .endE3ail,
em se)uida $asta proceder com o enio do e-mail da mesma forma como anteriormente.
S possKel ainda #ue os dados de cone%*o do seu seridor :3?! n*o estejam confi)urados na
instala+*o do seu !"!, isso n*o impede #ue oc& realize o enio da mesma forma, mas nesse caso
oc& ter1 #ue passar esse dados atra7s da sua aplica+*o da forma apresentada a$ai%o e dar
prosse)uimento ao enio do e-mail:
6confi+ 7 array('a.th' 79 'lo+in'$
'./ername' 79 'my./ername'$
'pa//8ord' 79 'pa//8ord'"(
6protocolo 7 ne8 4endJailTran/port1mtp('mail'/er)idor'com'$ 6confi+"(
<niando 3ensa)ens em "?3@
- classe .endE3ail possui ainda um m7todo especKfico para o enio de mensa)em em "?3@, esse
m7todo 7 oset5od;"tml68, #ue al7m de rece$er a mensa)em a ser eniada no formato "?3@ ainda
confi)ura os ca$e+alhos necess1rios para #ue o e-mail seja eniado corretamente, alterando o
primeiro e%emplo para rece$er mensa)ens em "?3@ dei%aria o c2di)o da se)uinte forma:
6mail 7 ne8 4endJail("(
6mail-9/et;odyTe<t('Te<to do &-mail'"(
6mail-9/et;ody!TJL('ConteXdo em !TJL'"(
6mail-9/et1.0ject('A//.nto do Contato'"(
6mail-9/et%rom('remetenteWremetente'com'0r'$ '2emetente'"(
6mail-9addTo('de/tinatarioWde/tinatario'com'0r'$ 'De/tinatOrio'"(
6mail-9/end("(
0epare #ue apesar de incluir o m7todo set5od;"?3@68 nesse e%emplo o
m7todo set5od;?e%t68 ainda permanece sem altera+*o, o alor passado como parMmetro por esse
m7todo ser1 utilizado caso o destint1rio do e-mail n*o possa rece$er conte9do em "?3@.
Ane2ando Ar(ui"os ao E4mail
> .endE3ail ainda permite #ue sejam ane%ados ar#uios ao e-mail #ue est1 sendo eniado para
isso $asta incluir no c2di)o de enio de e-mail a se)uinte instru+*o anteriormente ao seu enio:
6mail-9createAttachment(6ar5.i)oAne<o"(
!assando como parMmetro uma instMncia do ar#uio #ue deseja eniar. 3uito proaelmente essa
instru+*o ir1 funcionar com a maioria dos ar#uios a serem eniados, mas al)uns ar#uios podem
necessitar de confi)ura+,es de 3ime?;pe ou <ncodin), para uma is*o mais completa desse tipo de
confi)ura+*o consulte ado!umenta'(o o-i!ial do -ramework
Adi&ionando Destinat0rios
>utros detinat1rios ainda podem ser adicionados ao e-mail conforme mostrado a$ai%o:
6mail-9addTo('de/tinatarioWde/tinatario'com'0r'$ 'De/tinatOrio P'"(
6mail-9addCc('de/tinatariocopiaWde/tinatario'com'0r'$ 'De/tinatOrio em
Copia'"(
6mail-9add;cc('de/tinatariooc.ltoWde/tinatario'com'0r'$ 'De/tinatOrio em
Copia Oc.lta'"(
No e%emplo acima o primeiro destinat1rio 7 um destinat1rio comum e os se)uintes s*o eniados em
'2pia e em '2pia >culta respectiamente.
Adi&ionando Cabeal8os
- classe .endE3ail ainda possui outros m7todos para incluir al)uns dos ca$e+alhos mais comuns nos
e-mails, al)uns desses m7todos s*o listados a$ai%o:
6mail-9/et2eplyTo('re/po/taWremetente'com'0r'"(
6mail-9/etDate(6date"(
6mail-9/etJe//a+eId(6id"(
> primeiro deles confi)ura um endere+o de resposta ao e-mail, o se)undo uma data para o e-mail e
o terceiro um (d para a mensa)em. -inda assim se oc& precisar utilizar o ca$e+alho #ue n*o esteja
presente em nenhum dos m7todos do .endE3ail oc& pode fazer isso atra7s do
m7todo add"eader68 #ue rece$e como primeiro parMmetro o nome do ca$e+alho e como
parMmetros se)uinte o6s8 alor6es8 desse ca$e+alho, da se)uinte forma:
6mail-9add!eader('I-JailYenerator'$ 'NomeDaAplicacao'"(
'onclus*o
> .end /ramework conse)ue fazer de uma tarefa simples como o enio de e-mail al)o mais simples
ainda, e ainda implementa al)umas noas funcionalidades ao enio de e-mail com a mesma
simplicidade, com isso 7 possKel fazer o enio de e-mail diretamente atra7s da sua aplica+*o.
'riando uma Nuem de ?a)s com .endE?a)
=esenoler nuens de ta)s com !"! puro pode ser um tra$alho um pouco comple%o pois nunca se
poder1 preer #uantas ta)s estar*o disponKeis ou #uantos itens estar*o relacionados com cada um
dessas ta)s, porem com .end /ramework esse tra$alho fica muito mais f1cil.
Criando uma /u"em de Ta!s
'omo em #uase tudo no .end /ramework e%istem diferentes formas de se criar um nuem de ta)s,
a maneira #ue irei apresentar nesse arti)o 7 a maneira automatizada de fazer esse processo,
utilizando .endE?a)E'loud #ue )er1 uma lista n*o ordenada 6JulF8 com os elementos da nuem de
ta)s sendo atri$uido a cada um dos elementos um link, o c2di)o a$ai%o demonstra como 7 simples
criar essa nuem de ta)s:
6n.)em 7 ne8 4endTa+Clo.d(array(
'ta+/' 79 array(
array('title' 79 'Tecnolo+ia'$ '8ei+ht' 79 HP$
'param/' 79 array('.rl' 79 '/ta+/tecnolo+ia'""$
array('title' 79 'Ne+ocio/'$ '8ei+ht' 79 PZ$
'param/' 79 array('.rl' 79 '/ta+/ne+ocio/'""$
array('title' 79 'J.ndo'$ '8ei+ht' 79 C[$
'param/' 79 array('.rl' 79 '/ta+/m.ndo'""$
"
""(
echo 6n.)en/(
No c2di)o acima tudo #ue foi feito foi criar uma instMncia da classe .endE?a)E'loud e passar ao
seu construtor uma arra; de op+,es com somente a op+*o Vta)sW #ue rece$e um outro arra; com as
informa+,es so$re cada uma das ta)s #ue est*o sendo utilizadas, essas informa+,es s*o, o nome da
ta) 6title8, o peso da ta) 6wei)ht8 e um terceiro parMmetro com a A0@ #ue dee ser inserida no link
dessa ta) 6url8.
!ara o peso da ta) oc& pode passar o n9mero de elementos #ue est1 relacionado a cada uma das
ta)s, dessa forma #uando o .endE?a)E'loud for )erar a nuem de ta)s ele ir1 atri$uir tamanhos de
fonte maiores Ls ta)s #ue se relacionarem com mais elementos e menores a#uelas #ue se
relacionarem com menos elementos.
>utros aspectos da nuem como tamanho das fontes ou mesmo #uais elementos de "?3@ ser*o
utilizados ao redor de cada item da nuem podem ser controlados por =ecorators, para uma lista
completa desses decorators consulte o manual da classe Zend/Tag/Cloud. Nesse mesmo manual
oc& poder1 encontrar mais informa+,es so$re outras formas de se tra$alhar com Nuens de ?a)s
com .end /ramework.
Con&luso
-tra7s da forma apresentada oc& conse)uir1 criar sua pr2pria nuem de ta)s para o $lo) ou site
#ue estier desenolendo, essa forma de se tra$alhar com Nuem de ?a)s dee resoler em 90\
dos casos, mas caso oc& precise desenoler Nuens de ?a)s mais comple%as com mais elementos
e op+,es o ./ tam$7m permite isso seja realizado sem muito esfor+o, por7m, meu o$jetio com
esse arti)o era apenas mostrar uma das formas mais pr1ticas de se tra$alhar com esse elemento de
um site, espero #ue tenham )ostado e sintam-se a ontade para utilizar o campo de coment1rios
caso precisem de mais al)uma informa+*o.
/iltros e alidadores s*o comumente usados junto com formul1rios, mas essa pr1tica j1 foi relatada
no arti)o so$re /ormul1rios com .end /ramework, a)ora pretendo falar um pouco so$re como
utilizar esses mesmos filtros em outras situa+,es #ue n*o enolam formul1rios.
6 (ue so Filtros
- diferen+a $1sica entre filtros e alidadores e #ue en#uanto os alidadores apenas erificam se
um determinado alor condiz com a#uilo #ue 7 re#uerido e retorna o resultado dessa alida+*o
sem alterar o alor fornecido no inKcio os filtros tentam alterar esse alor para #ue ele se ade#ue
ao necess1rio. !ara e%emplificar di)amos #ue precisamos rece$er de al)uma aplica+*o uma strin)
no formato 'amel'ase 6cada palara da strin) come+ando com letras mai9sculas8, mas o #ue
acontece 7 #ue na erdade rece$emos uma strin) no formato strin)Edash 6palaras separadas por
GEH8, se su$metermos o alor rece$ido a um alidador ele ir1 apenas retornar a informa+*o de #ue
a :trin) rece$ida n*o se ade#ua ao padr*o necess1rio 6false8 en#uanto se su$metermos a mesma
strin) a um filtro 6=ash?o'amel'ase68 nesse e%emplo8 ele ir1 tentar alterar o alor para coincidir
com o padr*o e ent*o ir1 retornar o alor j1 alterado.
Uso 10si&o dos Filtros
- Atiliza+*o de filtros com .endE/ilter 7 $astante simples, para sua e%ecu+*o $asta criar um
instMncia da classe do filtro desejado 6!ara um lista completa das classes suportadas consulte a
documenta+*o da classe .endE/ilter8 e em se)uida chamar o m7todo filter68 dessa classe passando
como parMmetro o alor #ue dee ser filtrado, da se)uinte forma.
6filter 7 ne8 4end%ilterDi+it/("(
echo 6filter-9filter('*alor com NXmero/ CPH'"( // CPH
No e%emplo acima foi usada a classe .endE/ilterE=i)its #ue remoe todos os caracteres #ue n*o
s*o num7ricos de uma strin) dei%ando apenas os n9meros, nesse e%emplo ser1 impresso na tela o
alor G12P[.
Filtros em Cas&ata
<m al)uns casos 7 preciso usar uma s7rie de filtros na se#u&ncia para se conse)uir o resultado
desejado, esse processo 7 #uase t*o simples #uanto a utiliza+*o de filtros indiiduais, para isso
$asta criar uma instMncia da classe .endE/ilter e atra7s do m7todo addfilter68 adicionar os filtros
desejados L se#u&ncia, por fim chamar o m7todo filter dessa classe da mesma forma como
anteriormente, o e%emplo a se)ui ilustra o #ue foi dito:
6/trin+ 7 B\pala)ra\B(
6ca/cata 7 ne8 4end%ilter("(
6ca/cata-9add%ilter(ne8 4end%ilterAlpha(""
-9add%ilter(ne8 4end%ilter1trin+ToGpper(""(
6/trin+%iltrada 7 6ca/cata-9filter(6/trin+"(
Nesse e%emplo 7 preciso #ue sejam eliminados os caracteres n*o alphanumericos
6.endE/ilterE-lpha8 de uma strin) e em se)uida 7 preciso transformar os caracteres dessa strin)
em letras mai9sculas 6.endE/ilterE:trin)?oApper8, a saKda desse e%emplo ser1 portanto o termo
G!-@-D0-H.
Criando Filtros Personali)ados
-pesar de e%istir um )rande n9meros de filtros natios no .end /ramework 7 possKel #ue oc&
precise realizar um filtro #ue n*o esteja presente natiamente, um e%emplo $astante comum disso
no 5rasil 7 a formata+*o do '<! para o formato NNNNN-NNN a partir de uma entrada num7rica. !ara
isso $asta criar uma classe da se)uinte forma:
cla// %iltraCep implement/ 4end%ilterInterface
=
p.0lic f.nction filter(6cep"
=
6inicio 7 /.0/tr(6cep$ A$ ["(
6termino 7 /.0/tr(6cep$ ["(
6cep%iltrado 7 6inicio''-''6termino(
ret.rn 6cep%iltrado(
>
>
< depois utilizar a classe da mesma forma #ue um filtro comum:
6filter 7 ne8 %iltraCep("(
echo 6filter-9filter('AAAAAAAA'"( // AAAAA-AAA
Nesse e%emplo tudo #ue foi feito foi criar uma classe /iltra'ep #ue implementa a classe
.endE/ilterE(nterface e nela criar um m7todo filter68 #ue rece$e o cep n*o formatado como
parMmetro, separa essa strin) em duas partes 6Oinicio e fim8, concatena com um hKfen 6G-H8 e
depois retorna o alor formatado.
Nesse e%emplo utilizamos G/iltra'epH como nome dessa classe, mas 7 interessante #ue oc&
nomeia essa classe se)uindo as $oas pr1ticas de nomenclatura do .end /ramework para #ue oc&
possa usufruir das anta)ens do -utoload, caso contr1rio oc& ter1 #ue incluir o ar#uio da classe
manualmente no seu 'ontroller.
Con&luso
-tra7s desses e%emplos procurei demonstrar como utilizar os filtros presentes no .end /ramework
fora do conte%to do formul1rio, apesar de eles serem mais utilizados em conjunto tam$7m 7 muito
comum necessitar desses filtros fora desse conte%to, e 7 muito melhor utilizar as classes j1
e%istente do #ue criar noas classes para fazer a mesmo coisa e muito melhor ainda do #ue realizar
itera+,es nos alores manualmente.
Dalida+*o com .endEDalidate
=a mesma forma como os filtros podem ser usados fora do conte%to dos formul1rios os alidadores
tam$7m podem esse arti)o tem como o$jetio demostrar as demais formas de uso dos alidadores
com dados proenientes de outros lu)ares.
6 (ue so *alidadores
No arti)o anterior so$re /iltros descrei a diferen+a $1sica entre os filtros e alidadores como
sendo referente a altera+*o realizada no dado inicial, ao contr1rio dos filtros #ue realizam
altera+,es nesses dados os alidadores somente erificam se esse dado est1 de acordo com os
padr,es necess1rios e retorna um alor $ooleano como resposta.
Uso 10si&o dos *alidadores
> uso dos alidadores 7 $astante parecido com o uso dos filtros, por7m como o retorno do m7todo
isDalid68 7 um alor $ooleano podemos usar esse m7todo juntamente com uma clausula condicional
para realizar opera+,es diferentes caso o alor seja 1lido ou n*o, o e%emplo a se)ui ilustra essa
pr1tica.
6/trin+ 7 Ba0cdeB(
6)alidador 7 ne8 4end*alidateAlpha("(
if (6)alidador-9i/*alid(6/trin+"" =
echo B1trin+ cont]m apena/ caractere/ alpha0etico/B(
> el/e =
foreach (6)alidador-9+etJe//a+e/(" a/ 6me//a+eId 79 6me//a+e" =
echo B%alha na *alidaTRo '6me//a+eId'- 6me//a+e^nB(
>
>
Nesse e%emplo foi criada uma ari1el Ostrin) e atri$uKdo o alor Ga$cdeH L ela, da mesma forma
foi criada uma instMncia da classe .endEDaidadeE-lpha #ue 7 a classe respons1el por erificar se o
alor passado para seu construtor contem apenas caracteres alfanum7ricos, o
m7todo isDalid68 dessa classe foi chamado sendo passado como parMmetro para ele a strin)
anteriormente definida dentro de uma cl1usula condicional.
<ssa cl1usula condicional ir1 aaliar o retorno do m7todo e caso ele seja erdadeiro 6o #ue 7 o caso
no e%emplo8 imprimir1 na tela a informa+*o de #ue o alor passado cont7m apenas caracteres
alfanum7ricos. :e a strin) passada n*o contiesse apenas esse tipo de caracteres seria chamado o
m7todo )et3essa)es68 dessa classe #ue retorna um arra; de mensa)ens de erro na alida+*o e
essas mensa)ens seriam impressas na tela atra7s de um foreach68.
> .end /ramework possui ainda muitos outros alidadores atiamente implementados, para uma
lista completa desses alidadores oc& pode consultar a do!umenta'(o o-i!ial dos validadores.
*alidadores em Cas&ata
=a mesma forma como as ezes 7 preciso realizar filtros se#u&ncias em um determinado alor as
ezes tam$7m 7 necess1rio realizar alida+,es se#u&ncias, para isso $asta proceder da se)uinte
forma:
6/trin+ 7 Ba0cdeCPHB(
6)alidador7 ne8 4end*alidate("(
6)alidador-9add*alidator(ne8 4end*alidate1trin+Len+th(array('min' 79
Z$'ma<' 79 CP"""
-9add*alidator(ne8 4end*alidateAln.m(""(
if (6)alidador-9i/*alid(6/trin+"" =
echo B1trin+ cont]m entre Z e CP caractere/ alphan.merico/B(
> el/e =
foreach (6)alidador-9+etJe//a+e/(" a/ 6me//a+eId 79 6me//a+e" =
echo B%alha na *alidaTRo '6me//a+eId'- 6me//a+e^nB(
>
>
No e%emplo acima est1 sendo criada uma instMncia da classe .endEDalidate e os alidadores est*o
sendo adicionados pelo m7todo addDalidator68, nesse caso o primeiro alidador erifica se o alor
passado tem no mKnimo ] e no m1%imo 12 caracteres e o se)undo erifica se s*o todos
alfanum7ricos, o processo a se)uir 7 o mesmo utilizado pelo e%emplo com alidadores indiiduais.
Criando *alidadores Personali)ados
> .end /ramework possui diersos alidadores implementados natiamente, mas assim como no
caso dos filtros pode ser #ue oc& precise implementar um alidador personalizado, utilizando o
mesmo e%emplo do '<! noamente, por7m para implementar um alidador ao in7s de um filtro
isso seria feito da se)uinte forma:
cla// *alidateCep e<tend/ 4end*alidateA0/tract
=
con/t C&P 7 'Cep'(
protected 6me//a+eTemplate/ 7 array(
/elf--C&P 79 B'_)al.e_' nRo ] .m C&P *OlidoB
"(
p.0lic f.nction i/*alid(6)al.e"
=
6thi/-9/et*al.e(6)al.e"(
if (Epre+match('/`?A-K@=[>-?A-K@=H>6/'$ 6)al.e"" =
6thi/-9error("(
ret.rn fal/e(
>
ret.rn tr.e(
>
>
No c2di)o acima 7 criada uma classe DalidadeE'ep #ue estende a classe .endEDalidadeE-$stract e
implementa um m7todo isDalid68 #ue rece$e o alor a ser alidado como parMmetro e realiza as
erifica+,es necess1rias, nesse caso estou erificando o formato do '<! atra7s de uma e%press*o
re)ular #ue erifica se o alor possui ^ n9meros se)uidos de um hKfen e mais P n9meros 6o padr*o
do '<! no 5rasil8 e retorna falso caso n*o seja e erdadeiro caso esteja dentro do padr*o. -l7m
disso no come+o da classe foi definida uma mensa)em de erro #ue ser1 atri$uKda caso o alor
rece$ido n*o seja compatKel com esse padr*o.
-p2s a defini+*o da classe podemos utilizar esse alidador da mesma forma #ue os alidadores
natios do .endE/rameork, como mostrado a$ai%o:
6/trin+ 7 BAAAAA-AAAB(
6)alidador 7 ne8 *alidateCep("(
if (6)alidador-9i/*alid(6/trin+"" =
echo BC&P *OlidoB(
> el/e =
foreach (6)alidador-9+etJe//a+e/(" a/ 6me//a+eId 79 6me//a+e" =
echo B%alha na *alidaTRo '6me//a+eId'- 6me//a+e^nB(
>
>
Dale lem$rar noamente #ue 7 recomendado se)uir o padr*o de nomenclatura das classes no .end
/ramework caso oc& #ueira utilizar todos os recursos do -utoload do /ramework.
Alterando as ensa!ens dos *alidadores
>s alidadores natios do .end /ramework possuem suas mensa)ens padr,es j1 definidas, mas
pode ser #ue oc& #ueira altera-las, isso 7 $astante simples, o e%emplo a se)uir mostra como dee
proceder:
6)alidator 7 ne8 4end*alidateYreaterThan("(
6)alidator-9/etJe//a+e(
'O )alor informado nRo ] maior do 5.e o nece//Orio'$
4end*alidateYreaterThan--NOTY2&AT&2
"(
No e%emplo acima, estamos alterando a mensa)em do alidador #ue erifica se o alor passado 7
maior #ue o mKnimo esperado para uma mensa)em em portu)u&s atra7s do m7todo set3essa)e68,
#ue rece$e como primeiro parMmetro a noa mensa)em e como se)undo uma refer&ncia a
mensa)em #uem dee ser su$stituKda.
Con&luso
Dalidadores s*o $astante parecidos com filtros, ate mesmo na sua implementa+*o, al7m disso s*o
comumente utilizados juntamente com formul1rios mas tam$7m tem $astante utilidade fora desse
conte%to, a com$ina+*o dos alidadores com os filtros pode ajudar $astante na implementa+*o da
sua aplica+*o e ainda pode au%iliar na se)uran+a da mesma, 7 sempre recomendado #ue #ual#uer
dado proeniente do usu1rio, de outra aplica+*o e%terna ou #ue possa ter sido alterado fora do
conte%to da sua aplica+*o seja alidado e filtrado para #ue n*o hajam pro$lemas de
incompati$ilidade ou de se)uran+a, as classes do .end /ramework apresentadas nesse arti)o e no
anterior ajudam $astante nessa tarefa.
Diew "elpers com .end /ramework
3uitas ezes durante o desenolimento de uma aplica+*o precisamos criar uma fun+*o ou m7todo
#ue possa ser acessada diretamente na camada Diew, no .end /ramework 6e talez em outros
frameworks8 essas fun+*o s*o chamadas de Diew "elpers, s*o e%tremamente simples de se
desenoler e facilitam $astante al)umas tarefas da aplica+*o
*iews +el,ers /ati"as
Doc& pode n*o estar familiarizado com o nome GDiew "elpersH e pode at7 achar #ue nunca usou
al)o do tipo, mas o pr2prio .end /ramework possui al)uns desses m7todos implementados
natiamente, apenas para crit7rio de e%emplo ou listar al)uns deles a$ai%o:
url68 _ Atilizada para )erar links relatios a sua aplica+*o
$aseArl68 _ 0etorna a url $1sica da sua aplica+*o
Diew "elpers de /ormul1rios _ Ama para )erar cada um dos campos de formul1rio
- Diew "elper mais usualmente utilizada acredito #ue seja a url68, portanto ou utilizar ela pr2pria
para demonstrar seu funcionamento:
echo Othis-Furl6arra;6`module` UF `modulo`,`controller`UF`controlardor`,`action`UF`acao`8, null, ?0A<8X
'hamando essa iew helper diretamente no seu ar#uio de iew ir1 imprimir
G/modulo/controlador/acaoH, com isso oc& pode usar esse m7todo para criar links dinamicamente
dentro da sua aplica+*o.
Criando sua Pr,ria *iew +el,er
<m al)uns casos oc& precisa criar sua pr2pria Diew "elper para realizar al)uma tarefa #ue o .end
/ramework n*o faz natiamente, o e%emplo a se)uir mostra uma Diew "elper #ue retorna o nome
da sua aplica+*o para #ue esse seja utilizado em sua Diew:
cla// 4end*ie8!elperApplicationName e<tend/ 4end*ie8!elperA0/tract
=
p.0lic f.nction applicationName("=
ret.rn 'Nome da AplicaTRo'(
>
>
<ssa Diew "elper seria utilizada ent*o da se)uinte forma:
echo 6thi/-9applicationName("(
S um e%emplo simples de uso das Diews "elper mas atra7s desse m7todo oc& pode criar #ual#uer
fun+*o #ue desejar e essa fun+*o estar1 disponKel automaticamente para ser acessada na sua
camada de Diew. > ar#uio com a classe Diew "elper dee ficar dentro do diret2rio
Giews/helpers/-pplicationName.phpH caso oc& esteja usando a estrutura de diret2rios
recomendada pela .end.
Con&luso
-tra7s das Diews "elper oc& pode criar m7todos #ue fi#uem disponKeis diretamente na sua
camada de is*o, oc& pode realizar consultas ao $anco de dados para o$ter informa+,es #ue s*o
usadas com fre#u&ncia, pode realizar intera+,es com ari1eis, passar diersos parMmetros para
esses m7todos, ou seja, s*o in9mera possi$ilidades de utiliza+*o dessa funcionalidade no
/ramework, $asta adapt1-la as suas necessidades.
-ction "elpers com .end /ramework
No arti)o anterior falei um pouco so$re as iew helper, #ue s*o fun+,es ou m7todos criados para
serem acessados diretamente na camada de is*o da sua aplica+*o, hoje ou falar um pouco so$re
as -ction "elpers do .end /ramework.
6 (ue So A&tion +el,er
-ction "elpers s*o similares as Diew "elpers, criados para au%iliar nas fun+,es corri#ueiras de sua
aplica+*o por7m seu o$jetio e #ue sejam acessadas diretamente atra7s da sua camada de
'ontrole, al7m disso os -ction "elpers podem ser instanciados como classes normais podendo assim
ser manipulados de forma mais completa.
A&tion +el,ers /ati"as
> .end /ramework possui uma lista de -ction helpers #ue s*o implementadas natiamente, para
consultar essa lista $asta erificar a %o!umenta'(o O-i!ial dos "!tion #elpers apenas para demonstar
seu funcionamento irei utilizar de e%emplo a -ction "elper /lash3essa)e68 #ue tem como o$jetio
implementar um modo de passar mensa)ens entre um controlador e outro. - se)uir uma
demonstra+*o de seu funcionamento:
6thi/-9helper-9fla/hJe//en+er-9addJe//a+e('Jen/a+em a 1er Pa//ada'"(
> c2di)o acima mostra como adicionar uma mensa)em para #ue essa seja passada a outro
'ontroller, esse m7todo pode ser acessado diretamente do seu 'ontroller da forma e%ata como
apresentado acima. -p2s adicionar todas as mensa)ens necess1rias e em outros 'ontroller o
procedimento para recuperar essas mensa)ens 7 o se)uinte:
6thi/-9)ie8-9me//a+e/ 7 6thi/-9helper-9fla/hJe//en+er-9+etJe//a+e/("(
> c2di)o acima chama o m7todo )et3essa)es do -ction "elper em #uest*o #ue retorna um arra;
com as mensa)ens #ue foram adicionadas anteriormente, esse arra; 7 ent*o armazenado na
ari1el Othis-Fiew-Fmessa)e para #ue possa ser impresso na tela na camada de is*o da se)uinte
forma:
:,php foreach (6thi/-9me//a+e/ a/ 6me//a+e" - ,9
:p9:,php echo 6thi/-9e/cape(6me//a+e"( ,9:/p9
:,php endforeach( ,9
!ortanto atra7s desse -ction "elper 7 possKel passar mensa)ens necess1rias a sua aplica+*o de
um 'ontroller para outro de forma super simples.
Criando Seu Pr,rio A&tion +el,er
-ntes de criar um -ction "elper 7 preciso preparar a estrutura da aplica+*o para #ue possamos
armazenar os ar#uios de cada um desses -ction "elpers no lu)ar correto para isso crie dentro de
seu diret2rio li$rar; uma pasta nomeada de "elpers e em se)uida altere seu ar#uio 5ootstrap.php
para incluir a se)uinte instru+*o:
protected f.nction init!elper/("
=
4endControllerAction!elper;roNer--addPath(a!elperb"(
>
-)ora 7 possKel armazenar os helpers na pasta criada #ue o .end /ramework ir1 localiza-los
corretamente. !ara e%emplificar como s*o criados os -ction "elper amos criar a mesma fun+*o
#ue criamos no arti)o so$re Diews "elpers porem a)ora para #ue essa seja acessada pelo
controller:
:,php
cla// 4endControllerAction!elperApplicationName e<tend/
4endControllerAction!elperA0/tract
=
/33
3 W)ar 4endLoaderPl.+inLoader
3/
p.0lic 6pl.+inLoader(
/33
3 Con/tr.ctor- initialize pl.+in loader
3
3 Wret.rn )oid
3/
p.0lic f.nction con/tr.ct ("
=
// TODO A.to-+enerated Con/tr.ctor
6thi/-9pl.+inLoader 7 ne8 4endLoaderPl.+inLoader("(
>
p.0lic f.nction +etApplicationName("=
ret.rn BNome da AplicaTRoB(
>
/33
3 1trate+y pattern- call helper a/ 0roNer method
3/
p.0lic f.nction direct ("
=
ret.rn 6thi/-9+etApplicationName("(
>
>
5oa parte da classe acima foi )erada automaticamente pelo .endE?ool caso oc& tam$7m esteja
utilizando o .endE?ool ou o .end :tudio pode usufruir das suas facilidades para tornar o processo
mais simples, tudo #ue foi feito foi criar um m7todo applicationName68 #ue retorna o nome da
aplica+*o e alterar o m7tododirect68 para chamar esse mesmo m7todo. > m7todo direct68 7
chamado #uando -ction "elper 7 utilizado diretamente no 'ontroller, dessa froma e%istem duas
formas de chamar esse m7todo no seu 'ontroller:
6nomeAplicaTRo 7 6thi/-9helper-9applicationName("(
6helper 7 6thi/-9helper-9+et!elper(applicationName"(
6nomeAplicaTRo 7 6helper-9+etApplicationName("(
- primeira linha do c2di)o acima chama o helper diretamente o #ue far1 com #ue ele acesso o
m7tododirect68. -s duas linhas se)uintes criam um instMncia do helper e chamam o
m7todo )et-pplicationName68respectiamente. Nesse caso os dois modos ir*o produzir o mesmo
efeito mas caso seu helper possua mais de um m7todo oc& poder1 chama-los indiidualmente.
Con&luso
?anto Diews "elpers #uanto -ction "elpers podem ajudar $astante a realizar atiidades
corri#ueiras dentro de sua aplica+*o isto #ue permitem criar m7todos #ue fi#uem acessKeis na
camada de Dis*o ou na camada de 'ontrole da toda a aplica+*o, dessa forma n*o e%iste a
necessidade de se repetir a cria+*o da fun+*o sempre #ue necess1rio nem a necessidade de criar
um classe completa para ser incorporada ao /ramework.
'ria+*o de @a;outs com .end /ramework
<m $oa parte das aplica+,es e dos sites 7 muito comum #ue a interface isual do mesmo se
mantenha ao lon)o das p1)inas e somente seu conte9do e al)uns elementos isuais ariem de uma
p1)ina para outra, por isso 7 $astante desnecess1rio #ue toda essa interface isual seja totalmente
recriada a cada noa p1)ina #ue for criada, mesmo #ue isso se resuma a copiar e colar o c2di)o em
um noo ar#uio. !ara resoler esse pro$lema o .end /ramework possui a classe .end @a;out #ue
ser1 demonstrada nesse arti)o.
+abilitando o Zend 'a9out
!ara #ue o framework interprete #ue sua aplica+*o est1 utilizando a classe .endE@a;out para
renderizar a interface isual oc& primeiro precisa ha$ilitar seu funcionamento, o #ue 7 feito
inserindo no seu ar#uio 5ootstrap.php a se)uinte instru+*o:
p.0lic f.nction initLayo.t("=
4endLayo.t--/tartJ)c(array(
'layo.t'79 'defa.lt'$
'layo.tPath' 79 '''/application/)ie8///cript//layo.t'
""(
>
No c2di)o acima est1 sendo criado um m7todo Einit@a;out68 #ue ser1 e%ecutado no inKcio da
aplica+*o 6assim como #ual#uer outro m7todo iniciado por GEinitH criado na classe de 5ootstrap8 e
nele est1 sendo chamado o m7todo est1tico start3D'68 da classe .endE@a;out para esse m7todo
est1 sendo passado um arra; com dois elementos, o primeiro, cuja chae 7 Gla;outH informa o
nome do ar#uio do la;out #ue ser1 usado pela aplica+*o 6nesse caso GdefaultH8 e o se)undo
Gla;out!athH informa o caminho para esse ar#uio, nesse caso ele ser1 armazenado no diret2rio
application/iews/scripts/la;out.
Criando o 'a9out
-)ora #ue j1 o uso de .endE@a;out j1 foi ha$ilitado 7 preciso criar o ar#uio default.phtml dentro
do diret2rio application/iews/scripts/la;out, nesses e%emplos amos inserir a se)uinte marca+*o
"?3@ nele:
:EDOCTFP& html
PG;LIC B-//DHC//DTD I!TJL C'A Tran/itional//&NB
Bhttp-//888'8H'or+/T2/<htmlC/DTD/<htmlC-tran/itional'dtdB9
:html9
:head9
:meta http-e5.i)7BContent-TypeB content7Bte<t/html( char/et7.tf-MB
/9
:title9Jinha AplicaTRo com Layo.t:/title9
:/head9
:0ody9
:,php echo 6thi/-9layo.t("-9content(,9
:/0ody9
:/html9
?udo o #ue foi feito foi criar um ar#uio "?3@ simples com apenas uma instru+*o em !"! Gecho
Othis-Fla;out68-FcontentXH essa instru+*o ir1 inserir nesse local do c2di)o o conte9do da sua -ction.
Insero de Conte:do
-p2s o la;out ter sido ha$ilitado e criado oc& pode dar prosse)uimento ao desenolimento da sua
aplica+*o normalmente, para esse e%emplo amos criar a p1)ina inicial da sua aplica+*o, dessa
forma criaremos o ar#uio (nde%'ontroller no sue diret2rio de controllers da se)uinte forma:
:,php
cla// AdminInde<Controller e<tend/ 4endControllerAction
=
p.0lic f.nction init("=>
p.0lic f.nction inde<Action("=
6thi/-9)ie8-9tit.loPa+ina 7 'Tit.lo da PO+ina'(
>
>
No c2di)o acima foi criado o m7todo inde%-ction #ue rece$e apenas uma instru+*o criando a
ari1eltitulo!a)ina para ser passada para a iew #ue ficar1 da se)uinte forma:
:hC9:,php echo 6thi/-9tit.loPa+ina( ,9:/hC9
:im, isso mesmo, j1 #ue j1 criamos todo o ar#uio com o la;out anteriormente a iew s2 precisa
ter o conte9do da p1)ina mesmo, #ue no nosso e%emplo 7 s2 uma ta) h1 com o titulo da p1)ina,
o$iamente em um caso real haeria mais conte9do do #ue esse, mas isso n*o muda o fato de
torna o tra$alho com la;out muito mais simples.
$eali)ando C8amadas a 6utros Ar(ui"os no 'a9out
S muito pro1el #ue sua aplica+*o n*o tenha somente um titulo como conte9do, muito
proaelmente ela ter1 um menu, o c2di)o desse menu pode ser inserido juntamente com o
ar#uio default.phtml, mas tam$7m pode ser #ue oc& #ueira dei%a-lo em um ar#uio separado
para facilitar a manuten+*o, isso 7 muito simples, $asta criar dentro da mesma pasta do ar#uio
default.phtml um outro ar#uio 6#ue chamaremos de na.phtml8 e inserir a marca+*o do seu menu
nele, al)o similar ao apresentado a$ai%o:
:.l9
:li9:a href7Binde</inde<B9:/a9!ome:/li9
:li9:a href7Binde</ne8/B9:/a9Ne8/:/li9
:li9:a href7Binde</contatoB9:/a9Contato:/li9
:/.l9
> menu do e%emplo 7 composto de somente uma lista n*o ordenada de tr&s itens com links para
suas respectias p1)inas. -)ora 7 preciso alterar o ar#uio de @a;out para incluir a chamada para o
ar#uio do menu, ele ficar1 da se)uinte forma:
:EDOCTFP& html
PG;LIC B-//DHC//DTD I!TJL C'A Tran/itional//&NB
Bhttp-//888'8H'or+/T2/<htmlC/DTD/<htmlC-tran/itional'dtdB9
:html9
:head9
:meta http-e5.i)7BContent-TypeB content7Bte<t/html( char/et7.tf-MB
/9
:title9Jinha AplicaTRo com Layo.t:/title9
:/head9
:0ody9
:,php echo 6thi/-9render('na)'phtml'"(,9
:,php echo 6thi/-9layo.t("-9content(,9
:/0ody9
:/html9
> #ue foi feito foi somente incluir a refer&ncia ao ar#uio do menu lo)o antes do conte9do, nesse
caso o menu ser1 apresentado juntamente com sua p1)ina.
Tro&ando e Desabilitando o 'a9out
<m al)uns caso pode ser #ue uma determinada a+*o dentro da sua aplica+*o utilize um la;out
diferente ent*o ser1 necess1rio trocar esse la;out, tam$7m 7 possKel #ue outra a+*o n*o utilize
la;out al)um, nos dois casos a solu+*o 7 simples e 7 apresentada a$ai%o:
cla// AdminInde<Controller e<tend/ 4endControllerAction
=
p.0lic f.nction init("=>
p.0lic f.nction inde<Action("=
6thi/-9)ie8-9tit.loPa+ina 7 'Tit.lo da PO+ina'(
>
p.0lic f.nction ne8/Action("=
4endLayo.t--+etJ)cIn/tance("-
9/etLayo.t('no)olayo.t'phtml'"(
4endLayo.t--+etJ)cIn/tance("-
9/etLayo.tPath('''/application/)ie8///cript//no)olayo.t'"(
>
p.0lic f.nction contatoAction("=
4endLayo.t--+etJ)cIn/tance("-9di/a0leLayo.t("(
>
>
No e%emplo acima foram criadas mais duas -ctions, a primeira para a p1)ina de notKcias #ue
utiliza um la;out diferente, esse la;out est1 disponKel em um ar#uio noola;out.phtml na pasta
application/iews/scripts/noola;out conforme definido pelos
m7todos set@a;out68 e set@a;out!ath68respectiamente, j1 a outra -ction 7 respons1el pela
p1)ina de contato #ue n*o utiliza la;out, nesse caso o la;out foi desa$ilitado pelo
m7todo disa$le@a;out68 conforme mostrado acima.
Con&luso
<sse 7 apenas o $1sico so$re @a;out com .end /ramework, oc& pode fazer muitas outras coisas
com essa classe, mas s2 com isso j1 7 possKel perce$er #ue o .endE@a;out poupa muito do
tra$alho #ue seria )asto caso a mesma marca+*o "?3@ tiesse #ue ser reproduzida em todas as
p1)inas onde ela fosse usada. !ara uma is*o melhor das outras possi$ilidade da classe consulte
a do!umenta'(o o-i!ial da !lasse Zend/0a1out.
Terenciando 'onfi)ura+,es com .end /ramework
-r#uios de confi)ura+,es s*o muito comuns em .end /ramework, #uando um projeto com $ase no
.end ?ool 7 criado o pr2prio framework j1 armazana automaticamente al)umas confi)ura+,es em
ar#uios, mas o uso de confi)ura+,es com .end /ramework ai muito al7m disso, nesse arti)o
pretendo mostrar um pouco seu funcionamento.
A,rendendo a Usar Con%i!ura#es &om Zend Framework
-s informa+,es de confi)ura+,es no .end /ramework s*o armazanadas no formato chae-alor e o
uso mais $1sico de .endE'onfi) se da ao passar um arra; de confi)ura+,es para o construtor da
classe #ue ir1 interpreta-lo, permitindo #ue essas informa+,es sejam utilizadas como informa+,es
de confi)ura+,es da se)uinte forma:
6informacoe/ 7 array(
'applicationName' 79 'Nome da AplicaTRo'$
'applicationInfo' 79 array(
')er/ion' 79 'C'A'$
'de/cription' 79 'De/criTRo da AplicaTRo'
"
"(
> arra; acima possui al)umas informa+,es $1sicas da aplica+*o, para #ue essas informa+,es sejam
utilizadas atraes do .endE'onfi) $asta passas esse arra; como parametro ao instanciar a classe da
se)uinte forma:
Oconfi) U new .endE'onfi)6Oinformacoes8X
-p2s essa inicializa+*o 7 possKel recuperar cada uma dessas informa+,es da se)uinte forma:
6name 7 6confi+-9applicationName(
6)er/ion 7 6confi+-9applicationInfo-9)er/ion
-rmazenando as 'onfi)ura+,es em -r#uios
-rmazenar confi)ura+,es em ar#uios e #uase t*o simples #uanto o uso do .endE'onfi) com um
arra;, nesse arti)o amos utilizar como e%emplo ar#uios .ini, porem o .end permite ainda #ue
sejam utilizados ar#uios .json .%ml e .;aml oc& poder1 usar #ual#uer um de sua preferencia e
todos funcionar*o praticamente da mesma forma. !ara crit7rio de e%emplo amos utilizar as
mesmas informa+,es #ue forma utilizadas anteriormente e armazena-las em um ar#uio confi).ini
dentro do diret2rio application/confi)s com o se)uinte conte9do:
?prod.ction@
applicatioName 7 Nome da AplicaTRo
applicatioInfo')er/ion 7 C'A
applicatioInfo'de/cription 7 De/criTRo da AplicaTRo
?de)elopment - prod.ction@
applicatioInfo')er/ion 7 A'[
Note #ue al7m de armazenar as mesmas informa+,es #ue o e%emplo anterior nesse caso tam$7m
foi criada uma heran+a de confi)ura+,es onde a ers*o da aplica+*o do seridor de produ+*o 7
alterada #uando estamos tra$alhando em um seridor de desenolimento, a)ora podemos
recuperar essas informa+,es e e%i$i-las na rela da se)uinte forma da se)uinte forma:
6confi+ 7 ne8 4endConfi+Ini('''/application/confi+//confi+'ini'$
'de)elopment'"(
echo 6confi+-9applicationName( // imprime BNome da AplicaTRoB na tela
echo 6confi+-9applicationInfo-9)er/ion( // imprime BA'[B na tela
-lterando os -r#uios de 'onfi)ura+,es
> .end /ramework permite ainda #ue as informa+,es contidas nos ar#uios de confi)ura+*o sejam
dinamicamente alteradas pela aplica+*o, porem antes de tra$alhar com escrita em ar#uios 7
preciso se certificar #ue os ar#uios de confi)ura+*o tenham as permiss,es corretas permitindo
#ue eles sejam alterados, ap2s se certificar dessas permiss,es $asta realizar as altera+,es
conforme o e%emplo a$ai%o:
//Inicializa o 4endConfi+ e Cria o/ Am0iente/
6confi+ 7 ne8 4endConfi+(array("$ tr.e"(
6confi+-9prod.ction 7 array("(
6confi+-9/ta+in+ 7 array("(
//Define a/ !eranTa/
6confi+-9/et&<tend('de)elopment'$ 'prod.ction'"(
//Cria a/ *ariO)ei/ de Confi+.raTRo
6confi+-9prod.ction-9applicationName 7 'Nome da AplicaTRo'(
6confi+-9prod.ction-9applicationInfo 7 array("(
6confi+-9prod.ction-9applicationInfo-9)er/ion 7 'C'A'(
6confi+-9prod.ction-9applicationInfo-9de/cription 7 'De/criTRo da
AplicaTRo'(
6confi+-9de)elopment-9applicationInfo 7 array("(
6confi+-9de)elopment-9applicationInfo-9)er/ion 7 'A'['(
//&/cre)e a/ informaTUe/ no ar5.i)o 8riter'ini
68riter 7 ne8 4endConfi+DriterIni("(
68riter-98rite('''/application/confi+//8rite'ini'$ 6confi+"(
> c2di)o acima ir1 criar um ar#uio de confi)ura+*o e%atamente i)ual ao e%emplo anterior por7m
ir1 armazena-lo no ar#uio write.ini do mesmo diret2rio.
odi%i&ando In%orma#es de Ar(ui"os de Con%i!ura#es
-l7m de poder inserir noas confi)ura+,es em um ar#uio de confi)ura+*o oc& ainda pode alterar
as j1 e%istentes da se)uinte forma:
//Le o ar5.i)o de confi+.raTRo e ha0ilita a/ alteraTUe/
6confi+ 7 ne8 4endConfi+Ini('''/application/confi+//8rite'ini'$
n.ll$
array('/Nip&<tend/' 79 tr.e$
allo8Jodification/' 79 tr.e""(
//Altera o/ *alore/ De/ejado/
6confi+-9de)elopment-9applicationInfo-9)er/ion 7 'A'Z'(
//Altera a/ no)a/ informaTUe/ no ar5.i)o 8riter'ini
68riter 7 ne8 4endConfi+DriterIni("(
68riter-98rite('''/application/confi+//8rite'ini'$ 6confi+"(
=essa forma oc& estar1 alterando a confi)ura+*o de ers*o do sistema no am$iente de
desenolimento armazenada no ar#uio writer.ini de 0.^ para 0.].
Con&luso
> uso mais comun dos ar#uios de confi)ura+*o 7 o armazenamento das informa+,e de $anco de
dados, por7m s*o inumeras as possi$ilidade de utiliza+*o desse tipo de ar#uio, cada aplica+*o
poder1 ter uma )ama diferente de informa+,es de confi)ura+*o necess1rias e por isso 7 muito
importate sa$er utilizar o .endE'onfi) para usufruir de todo o poder do .end /ramework.
?raduzindo 3ensa)ens dos /ormul1rios do .end /ramework
-rti)o r1pido so$re como confi)urar a tradu+*o das mensa)ens de erro de alida+*o dos
formul1rios criados com .endE/orm a partir dos ar#uios de lin)ua)em disponKeis com a ers*o
completa do framework.
1ai2ando os Ar(ui"os &om as Tradu#es
>s ar#uios com as tradu+,es do .end /ramework est*o disponKeis somente com a ers*o
completa do framework #ue pode ser $ai%ada no :ite >ficial, esses ar#uios n*o est*o disponKeis
nem na ers*o mKnima do framework, nem mesmo s*o importados para o projeto #uando se realiza
a cria+*o da estrutura de diret2rios a partir do .endE?ool ou .end :tudio, por isso 7 fundamental
#ue o download da $i$lioteca completa seja realizado. -p2s realizar esses download descompacte
os ar#uios e copie a pasta GresourcesH #ue em junto com o framework para a raiz do diret2rio
do seu projeto.
Con%i!urando o 1ootstra,
5asicamente tudo #ue 7 preciso fazer para traduzir as mensa)ens de erro 7 confi)urar o seu
ar#uio de 5ootstrap para incluir a lin)ua)em desejada no tradutor padr*o da se)uinte forma:
p.0lic f.nction initTran/late(" =
6tran/lator 7 ne8 4endTran/late ( array ('adapter' 79 'array'$
'content' 79 '''/re/o.rce//lan+.a+e/'$ 'locale' 79 'pt;2'$ '/can' 79
4endTran/late--LOCAL&DI2&CTO2F " "(
4end*alidateA0/tract--/etDefa.ltTran/lator ( 6tran/lator "(
>
?udo #ue est1 sendo feito e criar uma instMncia da classe .endE?ranslate e passar um arra; com os
parMmetros de tipo de tradu+*o, caminho para os ar#uios de tradu+*o e lin)ua)em desejada, em
se)uida chamar o m7todo est1tico set=efault?ranslator68 da classe .endEDalidateE-$stract,
passando a instMncia da classe .endE?ranslate criada anteriormente.
Tradu)indo ensa!ens de Seus Pr,rios *alidadores
:e oc& mesmo criou um alidador personalizado e deseja #ue esse alidador tam$7m esteja
disponKel em mais de uma lin)ua)em, o processo 7 i)ualmente simples, dei%a a mensa)em de
alida+*o do corpo da sua classe de alida+*o em in)l&s, assim esse alidador se)uir1 o padr*o do
.end /ramework, em se)uida insira mais um item no arra; cuja chae dee ser a sua mensa)em de
alida+*o personalizada e o alor dessa ari1el a tradu+*o para a lin)ua)em desejada, como no
e%emplo a se)uir:
BJy Per/onal Je//a+eB 79 BJinha Jen/a+em Per/onalizadaB$
B'_)al.e_' i/ not a )alid C&PB 79 B'_)al.e_' nRo ] .m C&P )OlidoB$
:e oc& usou termos corin)a na sua mensa)em de erro, como V\alue\W, por e%emplo, oc&
tam$7m pode incluir esses alores corin)a na sua mensa)em de erro, como no se)undo e%emplo
acima.
Con&luso
'om isso oc& pode dei%ar as mensa)ens da sua aplica+*o na mesma lin)ua)em do restante da
aplica+*o sem ter #ue alterar todas as classes de alida+*o do framework.
-dcionando !a)inadores L !a)inas com .end /ramework
Quando n*o 7 possKel determinar o n9mero e%ato de resultados #ue podem aparecer em uma
p1)ina ou #uando esse n9mero de resultados 7 muito )rande, uma pr1tica e%celente 7 usar um
pa)inador para limitar o n9mero de resultados #ue ser*o e%i$idos em cada um das p1)inas, dessa
forma eita-se #ue uma p1)ina se torne muito e%tensa e #ue seu tamanho interfira no tempo de
carre)amento da mesma, al7m de dei%1-la muito mais a)rad1el isualmente.
Pa!inadores no Zend Framework
> .end /ramework possui uma classe de pa)ina+*o pr2pria, #ue facilita muito esse tra$alho e
ainda possi$ilita um e%celente controle do modo como esse pa)inador ser1 e%i$ido em p1)ina, a
classe .endE!a)inator permite ainda #ue 1rios tipos de dados sejam pa)inados, os tipos mais
comuns s*o dados contidos em um arra; e dados proenientes de um $anco de dados, nesse arti)o
iremos a$ordar apenas o 9ltimo desses tipos, mas a implementa+*o em cada um deles 7 $astante
semelhante.
Pa!inando $esultados do 1an&o de Dados
!ara realizar a pa)ina+*o de dados proenientes de um $anco de dados o$iamente 7 preciso ter
um $anco de dados, e pelo menos al)uns dados inseridos nele, n*o ou entrar no m7rito de cria+*o
desse $anco de dados, pois muitos arti)os anteriores j1 usaram diferentes $ancos de dados com
diferentes informa+,es e o processo de cria+*o de cada um desses $ancos j1 foi detalhado
anteriormente, nesse e%emplo ou apenas assumir #ue e%iste um $anco de dados, cuja cone%*o j1
est1 deidamente confi)urada no .end /ramework, com pelo menos uma ta$ela de usu1rios cujo
3odel tam$7m j1 foi criado.
Controller
> !a)inador de $anco de dados do .endE/ramework rece$e como parMmetro um conjunto de dados
proenientes do $anco 6rowset8 e a partir desse conjunto de dados e%i$e apenas os resultados
definidos pela confi)ura+*o desse pa)inador, o c2di)o a se)uir ilustra a parte dessa a+*o #ue 7
realizada no 'ontroller:
p.0lic f.nction inde<Action("=
6pa+ina 7 6thi/-9+etParam('pa+ina'$ C"(
6./erJodel 7 ne8 G/er("(
6ro8/etG/er 7 6./erJodel-9fetchAll("(
6pa+inador 7 4endPa+inator--factory(6ro8/etG/er"(
6pa+inador-9/etItemCo.ntPerPa+e(PA"(
6pa+inador-9/etPa+e2an+e(K"(
6pa+inador-9/etC.rrentPa+eN.m0er(6pa+ina"(
6thi/-9)ie8-9pa+inador 7 6pa+inador(
>
Nesse e%emplo todos os re)istros da ta$ela de usu1rio est*o sendo $uscados pelo
m7todo fetch-ll68 do 3odel de Asu1rios 6Ouser3odel8 e ent*o esses dados est*o sendo passados
para o m7todo est1tico factor;68 da classe .endE!a)inator, esse m7todo ir1 interpretar #ual o tipo
de dados est1 sendo passado para o pa)inador e realizar as a+,es necess1rias para o tipo em
#uest*o.
<m se)uida s*o feitas al)umas confi)ura+,es no pa)inador, a primeira delas e confi)urar o n9mero
m1%imo de itens por p1)ina para 20, se)uido do n9mero de p1)inas #ue ser1 e%i$ido nos controles
de p1)ina e por 9ltimo informando ao pa)inador #ual p1)ina deer1 ser e%i$ida, a
ari1el Opa)ina usada nesse caso armazena o n9mero de p1)ina #ue est1 sendo passado pela A0@
e caso isso n*o tenha ocorrido assume #ue o n9mero da p1)ina 7 1 6@inha 1 do '2di)o8. !or 9ltimo
o pa)inador e passado para a iew na ari1el Othis-Fiew-Fpa)inador.
Partial *iew
=epois de criar as a+,es no seu controller 7 preciso criar uma a estrutura dos controles de
pa)ina+*o, o c2di)o a$ai%o 7 um e%emplo desse tipo de estrutura, 7 uma altera+*o do e%emplo
contido na documenta+*o oficial do framework traduzido para o portu)u&s:
:,php if (6thi/-9pa+eCo.nt"- ,9
:di)9
:E-- Controle de PO+ina Anterior --9
:,php if (i//et(6thi/-9pre)io./""- ,9
:a href7B:,php echo 6thi/-9.rl(array('pa+ina' 79
6thi/-9pre)io./""( ,9B9\lt( Anterior:/a9 #
:,php el/e- ,9
:/pan9\lt( Anterior://pan9 #
:,php endif( ,9
:E-- Controle N.m]rico de PO+ina --9
:,php foreach (6thi/-9pa+e/In2an+e a/ 6pa+e"- ,9
:,php if (6pa+e E7 6thi/-9c.rrent"- ,9
:a href7B:,php echo 6thi/-
9.rl(array('pa+ina' 79 6pa+e""( ,9B9:,php echo 6pa+e( ,9:/a9 #
:,php el/e- ,9
:,php echo 6pa+e( ,9 #
:,php endif( ,9
:,php endforeach( ,9
:E-- Controle de Prc<ima PO+ina --9
:,php if (i//et(6thi/-9ne<t""- ,9
:a href7B:,php echo 6thi/-9.rl(array('pa+ina' 79
6thi/-9ne<t""( ,9B9Prc<ima \+t(:/a9
:,php el/e- ,9
:/pan9Prc<ima \+t(://pan9
:,php endif( ,9
:/di)9
:,php endif( ,9
<sse c2di)o dee ser inserido dentro de um ar#uio .phtml nesse e%emplo ou assumir #ue esse
ar#uio est1 dentro do diret2rio iews/scripts/la;out/pa)inador.phtml mas oc& pode armazen1-lo
no lu)ar #ue achar melhor, o c2di)o acima tam$7m 7 apenas um e%emplo de estrutura possKel #ue
pode ser alterado para atender as necessidades especKficas de cada aplica+*o.
A&tion *iew
No ar#uio de iew da -ction em #uest*o tudo #ue precisa ser feito 7 o se)uinte:
:,php if (co.nt(6thi/-9pa+inador""- ,9
:.l9
:,php foreach (6thi/-9pa+inador a/ 6./er"- ,9
:li9:,php echo 6./er-9name( ,9:/li9
:,php endforeach( ,9
:/.l9
:,php endif( ,9
:,php echo 6thi/-9pa+inationControl(6thi/-9pa+inador$ '1lidin+'$
'layo.t/pa+inador'phtml'"( ,9
'omo 7 possKel er o dados est*o sendo e%i$idos normalmente como se iessem diretamente do
$anco de dados, a 9nica diferen+a 7 #ue ao final est1 sendo incluKda a instru+*o para e%i$ir o
pa)inador, o m7todo pa)ination'ontrol68 rece$e tr&s parMmetros, o primeiro deles 7 a instMncia do
pa)inador #ue est1 sendo utilizado, o se)undo 7 o estilo do pa)inador, para uma lista completa dos
estilos disponKel oc& pode acessar a =ocumenta+*o da 'lasse .endE!a)inator, e o 9ltimo
parMmetro e o caminho para o ar#uio com a estrutura dos controles #ue foi criado anteriormente.
!ara simplificar ainda mais esse processo oc& pode confi)urar os padr,es desse pa)inador
incluindo no seu ar#uio de 5ootstrap a se)uinte instru+*o:
p.0lic f.nction initPa+inator("=
4endPa+inator--/etDefa.lt1crollin+1tyle('1lidin+'"(

4end*ie8!elperPa+inationControl--/etDefa.lt*ie8Partial('layo.t/pa+inado
r'phtml'"(
>
/eito isso oc& pode alterar a chamada para os controles de pa)ina+*o 69ltima linha do c2di)o da
iew -ction no inKcio do t2pico8 para apenas a se)uinte instru+*o:
:,php echo 6thi/-9pa+inador( ,9
'onclus*o
'om .endE!a)inator e al)uns passos simples 7 possKel melhorar si)nificatiamente a e%peri&ncia
do usu1rio na p1)ina e ainda reduzir o tempo de carre)amento da mesma e o consumo de trafe)o
do seridor de hospeda)em.
-utentica+*o -tra7s de 5anco de =ados com .endE-uth
5oa parte das aplica+,es desenolidas para a we$ tem pelo menos uma pe#uena 1rea de acesso
restrito, essa 1rea pode restrin)ir o acesso a determinado conte9do somente para usu1rios
cadastrados ou pode at7 mesmo ser uma 1rea de administra+*o dessa aplica+*o, onde o acesso n*o
autorizado poderia trazer mais prejuKzos, por isso, 7 sempre importante desenoler uma forma
se)ura de erificar as credencias do usu1rio e isso fica ainda melhor se al7m de se)ura essa forma
puder ser t*o simples como a solu+*o disponKel no .end /ramework #ue ser1 apresentada nesse
arti)o.
A Classe Zend5Aut8
- classe .endE-uth do .end /ramework 7 respons1el por cuidar de todo o processo de
autentica+*o e armazenamento da se+*o de lo)in do usu1rio, dei%ando muito mais simples o
tra$alho de erifica+*o das credenciais de acesso e permitindo a utiliza+*o de diersos modo de
erifica+*o, incluindo erifica+*o de identidade atra7s do $anco de dados, atra7s do protocolo
"??! e at7 mesmo atra7s de seri+os como >pen(=. -l7m disso ela pode ser e%tendida para
realizar a erifica+*o por #ual#uer outro modo #ue n*o esteja disponKel natiamente. Nesse arti)o
apenas o m7todo de autentica+*o atra7s do $anco de dados ser1 apresentado, mas oc& pode
conferir a %o!umenta'(o O-i!ial da Classe Zend/"uth caso precise realizar a autentica+*o atra7s de
outro m7todo.
Autenti&ao Atra"3s de 1an&o de Dados
?a$ela de Asu1rios
!ara realizar a autentica+*o de usu1rio atra7s do $anco de dados 7 preciso ter uma ta$ela nesse
$anco com pelo menos duas colunas, o lo)in e a senha, para crit7rio de e%emplo nesse arti)o ou
adicionar tam$7m o nome completo do usu1rio, seu e-mail, al7m disso o campo de senha ser1
cripto)rafado usando 3=^ 6lem$rando #ue o uso de 3d^ para armazenar senhas n*o 7
recomendado pois 7 um al)orKtimo com )rande facilidade de #ue$ra, nesse caso usarei apenas
como e%emplo8. > dia)rama ao lado ilustra o $anco de dados #ue deer1 ser criado para esse
e%emplo e a$ai%o transcreo o c2di)o :Q@ desse $anco:
C2&AT& TA;L& dG/erd (
id int(CC" NOT NGLL AGTOINC2&J&NT$
nome )archar(P[[" NOT NGLL$
mail )archar(P[[" NOT NGLL$
lo+in )archar(P[[" NOT NGLL$
pa// )archar(P[[" NOT NGLL$
P2IJA2F e&F (id"
"(
> /ormul1rio
!ara criar uma ferramenta de lo)in precisamos criar um formul1rio por onde o usu1rio ir1 informar
seus dados para #ue esses sejam erificados.
:,php
cla// %ormLo+in e<tend/ 4end%orm
=
p.0lic f.nction init("
=
6lo+in 7 ne8 4end%orm&lementTe<t('lo+in'"(
6lo+in-9/etLa0el('Lo+in do G/.ario'"
-9/et2e5.ired(tr.e"
-9add%ilter('1tripTa+/'"
-9add%ilter('1trin+Trim'"(
6/enha 7 ne8 4end%orm&lementPa//8ord('/enha'"(
6/enha-9/etLa0el('1enha do G/.ario'"
-9/et2e5.ired(tr.e"
-9add%ilter('1tripTa+/'"
-9add%ilter('1trin+Trim'"(
6/.0mit 7 ne8 4end%orm&lement1.0mit('&ntrar'"(
6thi/-9add&lement/(array(6lo+in$ 6/enha$ 6/.0mit""(
>
>
> formul1rio acima contem apenas dois campos, o campo de lo)in e o campo de senha, al7m 7
claro do $ot*o #ue eniar1 esse formul1rio para #ue seus dados sejam processados, as informa+,es
so$re m7todo de enio 6T<? ou !>:?8 foram omitidas, mas 7 sempre $om lem$rar #ue 7 altamente
recomend1el passar dados de lo)in apenas por !>:? e nunca por T<? j1 #ue no se)undo caso eles
ficam isKeis na A0@.
6 Controller
!raticamente toda a erifica+*o de lo)in nesse e%emplo ser1 realizada no 'ontroller, por isso essa
parte necessita de um pouco mais de aten+*o, a$ai%o se)ue o c2di)o desse controller #ue ser1
deidamente e%plicado a$ai%o.
p.0lic f.nction lo+inAction("=
if(4endA.th--+etIn/tance("-9ha/Identity(""=
6thi/-9redirect('inde<'"(
>el/e=
6thi/-9)ie8-9form 7 ne8 %ormLo+in("(
if(6thi/-9+et2e5.e/t("-9i/Po/t(" and 6thi/-9)ie8-9form-
9i/*alid(6PO1T""=
6)al.e/ 7 6thi/-9)ie8-9form-9+et*al.e/("(
6d0Adapter 7 4endD0Ta0le--+etDefa.ltAdapter("(
6adapter 7 ne8
4endA.thAdapterD0Ta0le(6d0Adapter"(
6adapter-9/etTa0leName('G/er'"
-9/etIdentityCol.mn('lo+in'"
-9/etCredentialCol.mn('pa//'"
-9/etIdentity(6)al.e/?'./.ario'@"
-9/etCredential(6)al.e/?'/enha'@"
-9/etCredentialTreatment('JD[(,"'"((
6a.th 7 4endA.th--+etIn/tance("(
6re/.lt 7 6a.th-9a.thenticate(6adapter"(
if (6re/.lt-9i/*alid("" =
6thi/-9redirect('inde<'"(
>el/e=
6thi/-9)ie8-9form-9/etDe/cription('G/.Orio
o. 1enha In)Olido/'"(
>
>
>
>
Ama -ction de @o)in 6lo)in-ction8 est1 sendo criada e lo)o no inKcio dessa -ction est1 sendo
chamado um m7todo est1tico da classe .endE-uth para erificar se o usu1rio j1 est1 lo)ado, caso
ele j1 esteja ele 7 direcionado para a p1)ina inicial, caso n*o esteja o formul1rio criado
anteriormente 7 instanciado e armazenado na ari1el Othis-Fiew-Fform, ou seja est1 sendo
armazenado em uma ari1el e passado a is*o ao mesmo tempo.
@o)o em se)uida erificamos se e%iste uma re#uisi+*o !>:? a essa a+*o e caso e%ista se o alores
passados por essa re#uisi+*o s*o 1lidos de acordo com os parMmetros de alida+*o do formul1rio,
nesse ponto ca$e uma o$sera+*o, caso a re#uisi+*o n*o seja do tipo !>:? ou os alores n*o forem
1lidos o formul1rio ser1 e%i$ido na tela, ou seja, se o isitante ainda n*o enio nenhum dado para
o formul1rio ou se esses dados est*o errados 6apenas do ponto de ista de alida+*o de dados, n*o
de lo)in8 ele ser1 encaminhado ao formul1rio para eniar essas informa+,es ou corri)ir as
informadas anteriormente.
'aso a re#uisi+*o seja do tipo !>:? e os alores 1lidos che)ou a hora de erificar se as credenciais
est*o corretas. - primeira coisa a ser feita 7 re#uisitar o adaptador padr*o do $anco de dados
atra7s do m7todo.endE=$E?a$le::)et=efault-dapter68 e armazen1-lo em uma ari1el, j1 #ue
amos precisar dele mais tarde, caso n*o e%ista um adaptador padr*o preiamente confi)urado
ser1 necess1rio iniciar uma cone%*o ao $anco de dados. <m se)uida 7 criada uma instancia da
classe .endE-uthE-dapterE=$?a$le passando como parMmetro o adaptador do $anco citado
anteriormente, e essa instMncia 7 armazenada em uma ari1el.
> pr2%imo passo e passar as informa+,es so$re os dados #ue ser*o usados por essa classe atra7s
dos m7todos chamados lo)o em se)uida. > m7todo set?a$leName68 rece$e o nome da ta$ela de
usu1rios no $anco de dados, o m7todo set(dentit;'olumn68 rece$e o nome da coluna do $anco de
dados onde est1 armazenada a informa+*o de nome de usu1rio, set'redential'olumm por sua ez
rece$e o nome da coluna onde est1 armazenada a senha, os m7todos set(dentit; e set'redential
rece$em respectiamente os alores de lo)in e senha passados pelo usu1rio e por fim o m7todo
set'redential?reatment68 rece$e a informa+*o so$re o tratamento #ue ser1 fornecido a senha,
nesse caso estamos utilizando a fun+*o md^68 para cripto)rafar essa senha.
!or fim re#uisitamos a instMncia da classe .endE-uth e chamamos o m7todo authenticate passando
como parMmetro a instancia da classe .endE-uthE-dapterE=$?a$le j1 com as informa+,es
armazenadas, se o retorno desse m7todo for ?0A< redirecionamos o usu1rio a p1)ina inicial se for
/-@:< incluimos uma descri+*o ao formul1rio com as informa+,es de #ue o lo)in e senha est*o
incorretos e eniamos o isitante de olta ao formul1rio para #ue ele preencha corretamente as
informa+,es.
A *iew
- Diew nesse caso s2 tem mesmo #ue e%i$ir o formul1rio da se)uinte fora:
:hP9Ace//o 2e/trito a G/.Orio/ Cada/trado/:/hP9
:,php echo 6thi/-9form( ,9
-rmazenando (nforma+,es na :e+*o de @o)in
-tra7s do m7todo apresentado anteriormente foi possKel erificar as credenciais do usu1rio #ue
estaa realizando o lo)in e criar a se+*o de lo)in do mesmo, por7m nessa se+*o o 9nico dado #ue
foi armazenado foi o nome do usu1rio, por7m as ezes 7 preciso #ue mais dados #ue estejam
disponKeis na ta$ela do $anco de dados tam$7m sejam armazenados, para isso $asta realizar
apenas uma pe#uena altera+*o no controller #ue ficar1 da se)uinte forma:
p.0lic f.nction lo+inAction("=
if(4endA.th--+etIn/tance("-9ha/Identity(""=
6thi/-9redirect('inde<'"(
>el/e=
6thi/-9)ie8-9form 7 ne8 %ormLo+in("(
if(6thi/-9+et2e5.e/t("-9i/Po/t(" and 6thi/-9)ie8-9form-
9i/*alid(6PO1T""=
6)al.e/ 7 6thi/-9)ie8-9form-9+et*al.e/("(
6d0Adapter 7 4endD0Ta0le--+etDefa.ltAdapter("(
6adapter 7 ne8
4endA.thAdapterD0Ta0le(6d0Adapter"(
6adapter-9/etTa0leName('G/er'"
-9/etIdentityCol.mn('lo+in'"
-9/etCredentialCol.mn('pa//'"
-9/etIdentity(6)al.e/?'./.ario'@"
-9/etCredential(6)al.e/?'/enha'@"
-9/etCredentialTreatment('JD[(,"'"((
6a.th 7 4endA.th--+etIn/tance("(
6re/.lt 7 6a.th-9a.thenticate(6adapter"(
if (6re/.lt-9i/*alid("" =
6/tora+e 7 6a.th-9+et1tora+e("(
6/tora+e-98rite(6adapter-
9+et2e/.lt2o8O0ject(n.ll$'pa//'""(
6thi/-9redirect('inde<'"(
>el/e=
6thi/-9)ie8-9form-9/etDe/cription('G/.Orio
o. 1enha In)Olido/'"(
>
>
>
>
@o)o antes de redirecionar o usu1rio para a p1)ina inicial foi chamado o m7todo )et:tora)e68 da
classe .endE-uth e em se)uida chamado o m7todo write #ue rece$e como parMmetro o retorno do
m7todo )et0esult0ow>$jet68 #ue por sua ez pode rece$er como primeiro parMmetro uma lista de
colunas do $anco de dados #ue ser*o armazenadas 6nesse caso foi passado null, #ue far1 com #ue
todas as colunas sejam armazenadas8 e como se)undo parMmetro uma lista das colunas #ue n*o
ser*o armazenadas 6nesse caso passamos o nome da coluna #ue contem a senha8, ou seja, todas as
colunas e%ceto a #ue cont7m a senha ser*o armazenadas, depois de ter realizado esse processo
$asta realizar o se)uinte procedimento para e%i$ir as informa+,es da se+*o de lo)in:
echo 4endA.th--+etIn/tance("-9+etIdentity("( //2etorna o Lo+in do G/.Orio
me/mo 5.e .m 1tora+e nRo tenha /ido criado
echo 4endA.th--+etIn/tance("-9+etIdentity("-9nome( //2etorna o Nome do
G/.Orio
echo 4endA.th--+etIn/tance("-9+etIdentity("-9email( //2etorna o &-mail do
G/.Orio
'onclus*o
-tra7s da classe apresentada nesse arti)o 7 possKel realizar de forma f1cil e se)ura a
autentica+*o do usu1rio atra7s de diersos meios, a#ui apenas um desses meios foi mostrado mas
tenha certeza de #ue com pouca mudan+a no #ue foi apresentado 7 possKel se adaptar a #ual#uer
#ue seja a sua necessidade.
0e#uisi+,es N3@-0!' com .end /ramework
3uitas ezes durante o desenolimento de al)umas aplica+,es precisamos realizar cone%,es entre
dois seridores para eniar ou $uscar informa+,es, e%istem diferentes protocolos para realizar esse
tipo de atiidade, mas nesse arti)o ou tratar um pouco so$re o protocolo 0!', mais
especificamente so$re a ariante desse protocolo #ue transporta mensa)ens no formato N3@, o
N3@-0!'.
$eali)ando Cone2o &om um Ser"idor ;'4$PC
-ntes de se conectar a um seridor 7 preciso sa$er se esse seridor suporta o protocolo N3@-0!',
se esse seridor realmente suportar o protocolo muito proaelmente haer1 uma documenta+*o
da interface de cone%*o com esse seridor, oc& ir1 precisar dela para sa$er os nomes dos m7todos
#ue poder1 chamar para realizar as consultas ou eniar informa+,es.
'omo e%emplo ou assumir #ue est1 sendo feita uma cone%*o com um seridor, #ue suporta o
protocolo N3@-0!' e #ue est1 localizado no endere+o Ghttp://seridor.%mlrpc.com/%mlrpc.phpH, e
#ue implementa apenas um m7todo Gto<n)lishH da classe GtranslateH respons1el por rece$er
palaras ou frases em portu)u&s e retornar sua tradu+*o em in)l&s.
!ara se conectar a esse seridor tudo #ue precisa ser feito 7 o se)uinte:
6client 7 ne8 4endIml2pcClient('http-///er)idor'<mlrpc'com/<mlrpc'php'"(
<ssa instru+*o est1 criando uma instMncia da classe .endENml0pcE'lient, passando como
parMmetro o endere+o do seridor e armazenando essa instMncia na ari1el Oclient
$eali)ando C8amadas aos 3todos
!ara chamar o m7todo preiamente descrito tudo o #ue precisa ser feito 7 o se)uinte:
6re/.lt 7 6client-9call('tran/late'to&n+li/h'$ array('OlO J.ndo'""(
echo 6re/.lt( //!ello Dorld
<st1 sendo chamado o m7todo call da instMncia de classe armazenada anteriormente na
ari1el Oclientpassando como primeiro parMmetro o nome da classe e m7todo a serem chamados
separados por G.H e em se)uida um arra; com os parMmetros re#uisitados por esse m7todo, nesse
e%emplo apenas a frase em portu)u&s #ue dee ser traduzida, caso o m7todo do seridor tenha
sido corretamente implementado ele deer1 retornar a :trin) G"ello BorldH.
*eri%i&ando Erros e Faltas
Quando estamos tra$alhando com cone%,es com seridores diferentes muitos fatores podem
ocasionar falhar nessa comunica+*o e muitos deles n*o est*o so$ o controle do desenoledor,
nesse caso tudo o #ue se pode fazer 7 erificar se al)um erro ocorreu e informar essa falha, isso
pode ser feito atra7s de um $loco tr;-catch da se)uinte forma:
try=
echo 6client-9call('tran/late'to&n+li/h'$ array('OlO J.ndo'""(
>catch (4endIml2pcClient%a.lt&<ception 6e" =
echo 'Iml2pc %a.lt ?''6e-9+etCode("''@- ''6e-9+etJe//a+e("(
>catch (4endIml2pcClient!ttp&<ception 6e" =
echo '&rro de !TTP ?''6e-9+etCode("''@- ''6e-9+etJe//a+e("(
>
Nesse caso a re#uisi+*o Nml0pc est1 inserida dentro de um $loco tr;-catch, caso a mesma seja
$em sucedida ser1 impresso na tela a tradu+*o da :trin) eniada como parMmetro, caso contr1rio
e%istem duas possi$ilidades de erros, a primeira #uando a cone%*o foi realizada com sucesso mas o
seridor remoto retornou uma falta, isso pode acontecer caso a strin) eniada tenha al)um
caractere in1lido ou caso al)uma erifica+*o do seridor n*o tenha sido $em sucedida, nesse caso
7 impresso na tela o c2di)o e mensa)em de erro retornados pelo seridor.
>utra possi$ilidade 7 #ue ocorra uma falha na comunica+*o com o seridor, o seridor pode estar
fora do ar temporariamente ou n*o ser encontrado, nesse caso a classe .endENml0pc retorna um
erro de "??!, esse erro 7 impresso na tela juntamente com seu c2di)o da mesma forma #ue o
anterior. =essa forma 7 possKel controlar melhor a comunica+*o entre as duas aplica+,es.
Con&luso
'om .endENml0pc a comunica+*o entre duas aplica+,es se torna muita mais f1cil do #ue caso
fosse feita manualmente, com isso 7 possKel acessar -!( p9$licas ou propriet1rias #ue forne+am
suporte ao esse protocolo e melhorar si)nificamente a sua aplica+*o.
>$tendo (nforma+,es de -plica+,es <%ternas com .endE"ttp
- al)um tempo atras escrei um arti)o so$re Cone2(o !om Servidores 3*045PC, essa 7 uma das
formas de se o$ter informa+,es de uma aplica+*o e%terna, mas em al)umas ocasi,es as
informa+,es #ue se deseja $uscar est*o disponKeis pu$licamente e n*o 7 n*o e%iste um seridor
N3@-0!' para fornecer essas informa+,es, nesse caso podemos realizar re#uisi+,es "??! simples
no plano de fundo da aplica+*o para o$ter o conte9do de outros sites ou aplica+,es.
Ini&iando uma $e(uisio +TTP $emota7
!ara iniciar uma re#uisi+*o "??! remota tudo o #ue precisa ser feito 7 a$rir uma cone%*o com o
seridor e%terno atra7s do protocolo "??! usando para isso a classe .endE"ttp da se)uinte forma:
6client 7 ne8 4end!ttpClient(6recipient"(
Doc& ainda poder1 passar al)uma confi)ura+,es para essa re#uisi+*o, como por e%emplo limitar o
n9mero de redirecionamentos para 0, ou seja, n*o permitir #ue o seridor redirecione para outro
site ou aplica+*o, e limitar o tempo de resposta do seridor, para eitar pro$lemas caso o seridor
esteja indisponKel, essas confi)ura+,es podem ser feitas da se)uinte forma.
6client-9/etConfi+(array(
'ma<redirect/' 79 A$
'timeo.t' 79 HA""(
!assando !arMmetro para a 0e#uisi+*o.
-l7m de ajustar as confi)ura+,es de cone%*o ainda 7 possKel passar parMmetros para essa
re#uisi+*o, um e%emplo dessa utiliza+*o e caso seja necess1rio passar dados pelo m7todo !>:?,
usado fre#uentemente em formul1rios, o e%emplo a se)uir mostra a passa)em de al)uns dados
usando esse m7todo:
6client-9/etParameterPo/t(array(
'/earch' 79 'P/yco'$
'limit' 79 CA$
""(
6client-9/etJethod(4end!ttpClient--PO1T"(
No e%emplo acima estamos passando dois parMmetros atra7s do m7todo !>:?, o primeiro deles
seria um termo de $usca e o se)undo um limite de respostas #ue seriam e%i$idas, esses dados
poderiam ser passados para um mecanismo de $usca para o$ter seus resultados.
6btendo a $e,osta
=epois de realizar todas as confi)ura+,es e passar os parMmetros necess1rios 7 hora de rece$er as
resposta desse seridor, a instru+*o a se)uir demonstra como isso dee ser feito:
6re/pon/e 7 6client-9re5.e/t("(
<ssa instru+*o ir1 o$ter a resposta completa do seridor, o #ue incluKra o ca$e+alho do ar#uio e da
re#uisi+*o assim como todo o conte9do da p1)ina, oc& pode filtrar essa re#uisi+*o e o$ter
somente o ca$e+alho ou somente o conte9do atra7s das instru+,es a$ai%o:
6re/pon/e 7 6re/pon/e-9+et!eader("( //2ece0e o ca0eTalho
6re/pon/e 7 6re/pon/e-9+et;ody("( //2ece0e o conteXdo
'onclus*o
<%istem diersas formas de comunica+*o entre diferentes sites ou aplica+,es, anteriormente falei
um pouco so$re as re#uisi+,es N3@-0!', essa foi a ez de e%emplificar um pouco cone%,es
e%ternas utilizando o pr2prio protocolo "??!, cada cen1rio poder1 e%i)ir uma solu+*o diferente,
ca$e ao pro)ramador da aplica+*o definir #ual das solu+,es melhor se adapta as necessidades.

Das könnte Ihnen auch gefallen