Agosto 7th 2007 02:58 am
Zend Framework - Não estenda. Plugue!
Utilizando o plugin Zend_Controller_Plugin_ErrorHandler
-
$oFrontController = Zend_Controller_Front::getInstance();
-
$oFrontController->setControllerDirectory('/caminho/para/controllers');
-
-
$oErrorHandler = new Zend_Controller_Plugin_ErrorHandler();
-
//seta o controller que ira manipular o erro
-
$oErrorHandler->setErrorHandlerController('Error');
-
//seta a action que ira manipular o erro
-
$oErrorHandler->setErrorHandlerAction('handler');
-
//adiciona o plugin ao front controller
-
$oFrontController->registerPlugin($oErrorHandler);
-
-
$oFrontController->dispatch();
A partir deste código dizemos que nosso front controller irá redirecionar as exceções para o controller ErrorController::handlerAction().
Ao redirecionar o erro ocorrido para a action o plugin adiciona uma variável no request chamada 'error_handler', a qual o valor é um objeto do tipo ArrayObject com as propriedades:
- type: tipo do erro ocorrido.
- request: requisição feita no momento do erro.
- exception: exceção lançada no erro.
Controller para manipular os erros
-
<?php
-
-
class ErrorController extends Zend_Controller_Action {
-
-
public function handlerAction() {
-
$oRequest = $this->getRequest();
-
-
//pega o objeto que contém o erro
-
$oErrors = $oRequest->getParam('error_handler');
-
-
//testa o tipo de erro
-
switch ($oErrors->type) {
-
case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER:
-
case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION:
-
$this->getResponse()->setRawHeader('HTTP/1.1 404 Not Found');
-
break;
-
default: //Zend_Controller_Plugin_ErrorHandler::EXCEPTION_OTHER
-
break;
-
}
-
-
//pega a exceção lançada no erro
-
$oException = $oErrors->exception;
-
-
//loga o erro
-
$oLog = new Zend_Log(
-
new Zend_Log_Writer_Stream('/tmp/application.log')
-
);
-
-
$oLog->debug($oException->getMessage() . "\r\n"
-
. "Request: " . $oErrors->request->getControllerName()
-
. "/" . $oErrors->request->getActionName() . "\r\n"
-
. $oException->getTraceAsString());
-
-
$this->getResponse()->appendBody("Ocorreu um erro inesperado! :-)");
-
}
-
}
No exemplo acima, criamos uma action para manipular o tratamento das exceções, primeiramente pegamos o erro setado no parametro error_handler.
-
$oErrors = $oRequest->getParam('error_handler');
Logo após isso, verificamos qual o tipo de erro, através da variável type da instância do ArrayObject.
-
switch ($oErrors->type)
Aqui tratamos os erros do tipo Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER e Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION, enviando um header para o browser indicando que a página não foi encontrada. Estes dois tipos de erros, ocorrem caso o controller ou a action roteados pelo router, não forem encontrados. Caso não seja este o motivo do erro (seja lançada uma exceção qualquer), o typo será Zend_Controller_Plugin_ErrorHandler::EXCEPTION_OTHER.
Abaixo logamos o erro ocorrido, e enviamos ao browser do usuário uma "amigável" mensagem explicando que ocorreu um erro não esperado.
Testando o tratamento de erros
Agora para testar o tratamento de erros basta lançar uma exceção qualquer na action e ver o resultado. Ou então entar acessar um controller/action não disponível.
10 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!. […]