Agosto 7th 2007 02:58 am
Zend Framework - Não estenda. Plugue!
Introdução
A arquitetura de controllers do Zend Framework inclui um sistema plugin que permite que o código do usuário seja chamado quando determinados eventos ocorrem durante o ciclo de vida do processo de roteamento dos controllers. Para cada evento do front controller são chamados os métodos dos plugins registrados a ele.
Os métodos chamados pelo front controller estão definidos na classe abstrata Zend_Controller_Plugin_Abstract, a qual, as classes para plugins do usuário devem estender.
- routeStartup() chamado antes que Zend_Controller_Front utilize o router para processar a requisição.
- routeShutdown() chamado após o roteamento da requisição.
- dispatchLoopStartup() chamado antes que Zend_Controller_Front entre no loop do dispatcher.
- preDispatch() chamado antes da action seja dispachada pelo dispatcher.
- postDispatch() chamado após a action ser dispachada pelo dispatcher.
- dispatchLoopShutdown() chamado após Zend_Controller_Front sair do loop do dispatcher.
Escrevendo um plugin:
-
<?php
-
require_once 'Zend/Controller/Plugin/Abstract.php';
-
-
class MeuPrimeiroPlugin extends Zend_Controller_Plugin_Abstract
-
{
-
-
}
Nenhum dos métodos da classe Zend_Controller_Plugin_Abstract são abstratos, isso significa que o usuário poderá estender apenas os métodos que achar necessário.
Usando um plugin:
-
$front = Zend_Controller_Front::getInstance();
-
$front->setControllerDirectory('/caminho/para/controllers')
-
->registerPlugin(new MeuPrimeiroPlugin());
-
$front->dispatch();
Para utilizar um plugin basta utilizar o método registerPlugin() da classe Zend_Controller_Front passando como parametro a instância da classe de plugin que se deseja utilizar. É possivel adicionar quantos plugins forem necessário.
Zend_Controller_Plugin_ErrorHandler
Este plugin já vem na distribuição do Zend Framework, com ele é possivel manipular exceções lançadas pelos controllers ou pelas actions.
Você pode utilizar este plugin para logar erros de sua aplicação, exibir páginas "amigáveis" caso ocorra um erro fatal, laçar erros HTTP do tipo 404 (página não encontrada) ou 500 (erro interno).
Por default, ao capturar alguma exceção, o plugin redireciona o fuxo da aplicação para a action ErrorController::errorAction(), mas você pode modificar isso através dos métodos:
- setErrorHandlerModule() seta o módulo para onde deve ser direcionado o erro.
- setErrorHandlerController() seta o controller para onde deve ser direcionado o erro.
- setErrorHandlerAction() seta a action para onde deve ser direcionado o erro.
- setErrorHandler() este método pode ser utilizado para setar módulo, controller e action de uma só vez, o parametro é um array associativo com as chaves 'module', 'controller' e 'action'.
Também é possivel setar o direcionamento do fluxo passando um array associativo ao construtor do objeto.
-
new Zend_Controller_Plugin_ErrorHandler(array(
-
'module' => 'meumodulo',
-
'controller' => 'meucontroller',
-
'action' => 'manipulaerro')
-
);
13 Comments »












(2 votos, média: 4 de 5)

felipe tonello on 10 Ago 2007 at 19:03 #
achei bem legal essa abordagem de plugin..
eu sabia que podia fazer e tals mas nunca cheguei a utilizar mesmo..
Uma dúvida que tive, foi pq você usou o routeShutdown() ao invez do preDispatch() por exemplo?
Porque você precisa do route né? para saber qual é o controller usado para ver se não está usando o controller login?!
Intendi, mas sei lá, não fica 100% seguro dessa maneira… porque por exemplo o Zend_Controller_Action::__construct() é rodado, juntamente com os inits() e etc.. aí alguma informação pode ser usada sem necessiade..
A solução seria você utilizar os inits() e etc de acordo a sua lógica de plugin.
Parabéns!
diegotremper on 11 Ago 2007 at 04:55 #
Exato, você esta certo, também pensei nisso quando utilizei, mas ainda sim, gosto da idéia de utlizar os plugins para fazer o trabalho que sugeri de segurança, basta tomar alguns cuidados. Cheguei a progurar algo na lista de MVC do Zend para ver se ninguem tinha pensado algo parecido, mas não encontrei, acho que vou postar lá essa situação e ver o que o pessoal acha.
Valeu.
felipe tonello on 11 Ago 2007 at 16:20 #
Eu vi um modo de segurança igual a esse, com plugins mesmo, mas só que usando Acl.
Lá no devzone da zend mesmo, só que está em versão do ZF atrasada. Eu estou fazendo um aqui versão atualizada e usando para testes também..
Até mais diego,
Felipe
Aziz on 13 Out 2007 at 10:53 #
eu usei esse esquema de plugin em um sistema que estou desenvolvendo para renderizar cabeçalho e rodapé das paginas, mas acabei desfazendo o plugin pq não consegui fazer o titulo ficar customizado para cada pagina, a solução que arrangei foi extender a classe Zend_Controller_Action sobrescrevendo o metodo render().
fazendo algo assim:
public function render($action = null, $name = null, $noController = false)
{
#renderiza topo
$this->getResponse()->prepend(’topo’, $this->view->render(’topo.phtml’));
parent::render($action,$name,$noController);
#renderiza o rodape
$this->getResponse()->append(’rodape’, $this->view->render(’rodape.phtml’));
}
ta funfando blz, mas gostaria de saber se vc tem alguma ideia melhor?
Falow
Diego Tremper on 15 Out 2007 at 00:02 #
hum…
uma forma de fazer o que você fez é colocar dentro de cada view sua o seguinte código:
< ?php echo $this->render(’topo.phtml’); ?>
….
< ?php echo $this->render(’rodape.phtml’); ?>
[]’s
lamonato on 15 Nov 2007 at 16:20 #
Acabei fazendo como o diego, colocando dentro das views.
Parabéns pelo blog
Leonildo on 28 Abr 2008 at 16:15 #
Qual o diretório mais indicado para se colocar os plugins ?
Bruno on 14 Jul 2008 at 16:44 #
Ótimo, agradeço muito ao Diego, Felipe e Flavio Gomes por serem pioneiros aq no Brasil com esse Know-how sobre ZendFramework…me ajudaram muito….valeu mesmo…logo, logo quem sabe eu tambm naum ajude o pessoal!
links for 2008-08-02 [delicious.com] « sySolution on 02 Ago 2008 at 13:00 #
[…] Blog do Tremper » Zend Framework - Não estenda. Plugue! (tags: zend) […]
Blog do Tremper » Injeção de dependência com Zend Framework on 29 Nov 2008 at 03:50 #
[…] Porém, existem maneiras mais fáceis (e mais elegantes) de fazer isso. Injeção de Dependência é uma delas. Com o Zend Framework existem alguns pontos onde podemos aplicar este tipo de abordagem, utilizando Action Helpers, View Helpers e Plugins. Já expliquei aqui no blog como utilizar plugins, no post Não estenda. Plugue!. […]
Luiz on 23 Jan 2009 at 14:53 #
Olá,
Parabéns pelo blog, você já me ajudou e ensinou muita coisa com suas publicações.. obrigado mesmo…
Olha só ,lí seu tópico umas 50 vezes, mas não estou conseguindo adaptar para meu problema, e gostaria de uma ajudinha se possível…
Meu problema:
Estou iniciando no Zend e estou montando um menu dinâmico, ou seja, o usuário escolhe o módulo que deseja trabalhar e o Zend acessa o banco de dados e restagada somente os menus referente ao módúlo escolhido… até aí tudo em ordem…
Meu problema é que tenho um controller chamado MenuController.php e ModuloController.php, sendo que respectivamente o Menu acessa a tabela Menu e o Modulo a tabela de módulos disponíveis (exemplo: Compras, Viagens, Requisição de Compras…etc)
A idéia é que quando o usuário acessar uma página (qualquer controller) o Zend faça uma espécie de require_once no controller chamado “montamenu” para que se crie o menu com as opções…..
Tentei quase de tudo, require_once, render, include, _forward, _redirect… e nada funcionou, tirando o _forward que deu certo mas não ficou uma programação dinâmica…. e sim muito manual…
Quando de muita pesquisa acabei batendo neste post que achei que seria minha solução, mas não estou conseguindo criar meu plugin para apenas carregar e montar o menu do banco de dados..
Para usar o plugin no zend tenho que registar ele no sistema, o registro se faz no bootstrap ? o plugin deve ser salvo dentro da pasta Controller ?
Segui se exemplo mas ele dá Class not Found… (hehehehe)
Terias por acaso um exemplo voltado para menus ?
Obrigado pela ajuda,
Luiz
Arian Maykon (Dead_Thinker) on 07 Fev 2009 at 20:46 #
@Aziz - Cara, acho que se tu estudar e usar o Zend_Layout resolve teu problema de uma forma mais elegante. Dá uma olhada.
@Luiz - acho que pro teu caso mano seria melhor um View_Helper não? E nele tu poderia pegar dados da requisição/sessão e montar o menu conforme desejado. Dá uma sakada, uso um View_Helper pra renderizar os menus.
Thiago Colares on 09 Out 2009 at 12:14 #
Muito bom o post, parabéns pelo blog