Consultez la FAQ sur le ZF avant de poster une question
Vous n'êtes pas identifié.
Pages: 1
Bonjour,
Je suis en train de finaliser une application utilisant le Zend Framework et je bloque sur la gestion des erreurs 404.
Quelle genre d'implémentation utilisez vous ? Est-ce efficace ?
Damien
Hors ligne
Tu laisses le dispatcher lancer une exception si il ne trouve pas de controller/action correspondant a la demande et tu captures l'exception, dans le traitement c'est ta 404
Hors ligne
Oui, je l'utilise actuellement pour récupérer les exceptions durant le développement.
Ce que j'aimerais pouvoir faire c'est récupérer l'erreur sauf si c'est une erreur du controller style: controller XYZ non trouvé, la logger et envoyer une erreur 500.
Sinon un controller non trouvé, bien renvoyer une page au navigateur un page avec le code 404 et non 200.
Est-ce faisable ? Si oui comment ?
Hors ligne
Tu devrais trouver se que tu cherche ici :
http://julien-pauli.developpez.com/tuto … ceptions2/
Hors ligne
2mx a écrit:
Tu devrais trouver se que tu cherche ici :
http://julien-pauli.developpez.com/tuto … ceptions2/
je viens de tester ton code et j'ai des pbs
voici ce que j'ai fait
<?php require dirname(__FILE__).'/Action.php'; /** * Contrôleur d'erreur de l'application. * * @author Julien PAULI adapté par Jean-Yves Terrien * */ class Exception_ErrorController extends Exception_Action { private $_exception; private static $errorMessage; private static $httpCode; public function preDispatch() { $this->_helper->viewRenderer->setNoRender(true); // ne rend aucune vue automatiquement $this->_exception = $this->_getParam('error_handler'); $this->_response->clearBody(); // on vide le contenu de la réponse $this->_response->append('error',null); // on ajoute un segment 'error' dans la réponse if (isset($this->_exception->type)) { //Ajout du test sur appel direct du contrôleur switch ($this->_exception->type) { case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER: case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION: self::$httpCode = 404; self::$errorMessage = 'Page introuvable'; break; case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_OTHER: switch (get_class($this->_exception->exception)) { case 'Zend_View_Exception' : self::$httpCode = 500; self::$errorMessage = 'Erreur de traitement d\'une vue'; break; case 'Zend_Db_Exception' : self::$httpCode = 503; self::$errorMessage = 'Erreur de traitement dans la base de données'; break; case 'Metier_Exception' : self::$httpCode = 200; self::$errorMessage = $this->_exception->exception->getMessage(); break; case 'Autre_Exception' : self::$httpCode = 500; self::$errorMessage = 'Exemple avec une "autre exception"'; break; default: self::$httpCode = 500; self::$errorMessage = 'Erreur inconnue'; break; } break; } }else{ //si on a eu un appel manuel on retourne ok et le paramètre passé qui n'a pas forcément le bon type self::$httpCode = 200; self::$errorMessage = $this->_exception; } } public function displayAction() //je l'ai appelé display et non error pour faire /error/display plus parlant à mon avis { $this->getResponse()->setHttpResponseCode(self::$httpCode); $this->_errorMessage .= sprintf("<p>%s</p>",self::$errorMessage); } public function postDispatch() { $this->getResponse()->appendbody($this->_errorMessage,'error'); $this->getResponse()->appendbody('<a href="javascript:history.back()">retour</a>','error'); $config = Fast_Registry::getParameters(); //juste ma façon de récupérer la config if ($config->fast->get('debug')&&isset($this->_exception->type)) { $message = sprintf('<hr>DEBUG INFOS :<br /><strong>Exception de type <em>%s</em> <u>%s</u> envoyée dans %s à la ligne %d </strong> <p>Stack Trace : %s </p><hr>', get_class($this->_exception->exception), $this->_exception->exception->getMessage(), $this->_exception->exception->getFile(), $this->_exception->exception->getLine(), Zend_Debug::dump($this->_exception->exception,null,false) ); $this->getResponse()->append('debug',$message); } $this->getResponse()->append('debug',''); } }
pour le chargement je fais
Zend_Loader::loadClass('Zend_Controller_Plugin_ErrorHandler'); $plugin = new Zend_Controller_Plugin_ErrorHandler(); $plugin->setErrorHandlerModule('exception') ->setErrorHandlerController('error') ->setErrorHandlerAction('display'); Fast_Debug::show('$plugin',$plugin); $controller->registerPlugin($plugin);
j'ai testé l'appel à /exception/error/display et mon contrôleur fonctionne bien
j'ai tester l'appel à /exception/error/display/error_handler/test de message d'erreur et mon contrôleur fonctionne toujour bien
pour le dispatch j'ai
try { $controller->dispatch(); // dispatche ! } catch (Exception $exception) { // attrape toute exception if (class_exists('Fast_Debug')&&Fast_Debug::displayDebug()) { Fast_Debug::show('$exception', "$exception"); } else { exit($exception->getMessage()); } }
tout fonctionne comme avant et c'est bien la le problème.
car mon débug m'affiche ceci
Dans Front.php:107 $plugin => Zend_Controller_Plugin_ErrorHandler Object ( [_errorModule:protected] => exception [_errorController:protected] => error [_errorAction:protected] => display [_isInsideErrorHandlerLoop:protected] => [_exceptionCountAtFirstEncounter:protected] => 0 [_request:protected] => [_response:protected] => ) Appel de : Fast_Controller_Front::run()dans E:\Htdocs\Fast_Framework\index.php:78
pour ce qui est de la définition du pluggin
et lorsque j'appelle une action invalide
Dans Front.php:107 $plugin => Zend_Controller_Plugin_ErrorHandler Object ( [_errorModule:protected] => exception [_errorController:protected] => error [_errorAction:protected] => display [_isInsideErrorHandlerLoop:protected] => [_exceptionCountAtFirstEncounter:protected] => 0 [_request:protected] => [_response:protected] => ) Appel de : Fast_Controller_Front::run()dans E:\Htdocs\Fast_Framework\index.php:78 Dans Front.php:143 $exception => String { [] => exception 'Fast_Exception' with message 'Invalid controller specified (xxxx)' in E:\Htdocs\Fast_Framework\library\Fast\Controller\Dispatcher.php:29 Stack trace: #0 E:\Htdocs\Fast_Framework\library\Zend\Controller\Front.php(927): Fast_Controller_Dispatcher->dispatch(Object(Fast_Controller_Request_Http), Object(Zend_Controller_Response_Http)) #1 E:\Htdocs\Fast_Framework\library\Fast\Controller\Front.php(133): Zend_Controller_Front->dispatch() #2 E:\Htdocs\Fast_Framework\index.php(78): Fast_Controller_Front::run('application/con...') #3 {main} } Appel de : Fast_Controller_Front::run()dans E:\Htdocs\Fast_Framework\index.php:78
il passe donc dans mon débug dans le try pour le dispatch et non dans le controlleur error
mais je ne sais pourquoi.
j'ai retiré tout les débug en me disant qu'il perturbaient peut ête le système mais non rien de tout cela. mon exception n'est tout simplement pas trappée et le contrôleur d'erreur n'est pas appelé.
A+JYT
Dernière modification par sekaijin (19-02-2008 18:52:14)
Hors ligne
J'ai trouvé mon erreur
$controller->throwExceptions(true);
était écrit en dur juste avant la déclaration du plugin
Je vous résume ce que j'ai fait j'en ferai sun article plus tard.
Contrairement à julien je cherchais poi à afficher une page "normale" à mon utilisateur.
J'ai donc mis en place le même contrôleur mais il génère une vue. si mon paramètre debug est actif alors la vue contient l'exception formaté pour y voir clair
dans mon système de vue j'ai une notion de messager qui affiche une bulle de message lorsque l'application indique quelque chose à l'utilisateur.
ma vue utilise cela pour afficher un message à l'utilisateur. ce message sera toujours afficher débug ou pas.
pour faciliter le développement le message affiché est chargé depuis un fichier ini. en fonction de l'execption un message différent sera affiché. attention il s'agit ici de messages destinés à l'utilisateur final et non au développeur comme le sont les exceptions.
j'ai dans mes application une classe Fast_Exception et quelques autres qui en dérivent.
elle sont fait ainsi
class Fast_Exception_Model extends Fast_Exception { const FAST_MODEL_COMPONENT_NEED = ' need to by an Fast_Model_Component'; const UNDEFINED_METHOD = 'undefined method on model : '; }
j'utilise des constant pour mes exception. ainsi je l'ève des exception bien précise qui ne dépende pas d'un texte local à l'endoit ou elle sont levée.
throw new Fast_Exception_Model(Fast_Exception_Model::UNDEFINED_METHOD . $method);
de ce fait j'ai dans mes exceptions la possibilité de définir des méssage utilisateur dans mon fichier ini pour chaque classe d'execption applicative mais en plus de les spécifier pour une coonstante données.
mon contrôleur parcour la lite séquentiellement et vérifie que l'exception levée est une instance de celle dont il lit le message. on bénéficie ainsi de la capitalisation par dérivation. il suffit d'écrire ses méssages des plus spécifiques aux plus généreaux.
[messages] Fast_Exception_Action.UNDEFINED_ACTION.code = 404 Fast_Exception_Action.UNDEFINED_ACTION.message = 'Resource indisponible' Fast_Exception_Action.UNDEFINED_METHOD_NAME.code = 404 Fast_Exception_Action.UNDEFINED_METHOD_NAME.message = 'Resource indisponible' Fast_Exception_Action.UNDEFINED_MEMBER.code = 404 Fast_Exception_Action.UNDEFINED_MEMBER.message = 'Resource indisponible' Fast_Exception_Action.INVALID_CONTROLLER.code = 404 Fast_Exception_Action.INVALID_CONTROLLER.message = 'Resource indisponible' Fast_Exception_Action.INVALID_CONTROLLER_CLASS.code = 404 Fast_Exception_Action.INVALID_CONTROLLER_CLASS.message = 'Resource indisponible' Fast_Exception_Action.code = 503 Fast_Exception_Action.message = 'Erreur interne' Fast_Exception_View.code = 503 Fast_Exception_View.message = 'Erreur de traitement dans la présentation des données' Zend_View_Exception.code = 503 Zend_View_Exception.message = 'Erreur de traitement dans la présentation des données' Zend_Db_Exception.code = 503 Zend_Db_Exception.message = 'Erreur de traitement dans la base de données' Fast_Exception_Db.code = 503 Fast_Exception_Db.message = 'Erreur de traitement dans la base de données'
enfin j'ai rendu le tout complètement débrayable pas des clés dans le fichier de conf de l'application.
on peut ainsi traiter les exception avec ou sans le module et avec ou sans les débug.
sans rien on a le comportement standard
avec debug les exception sont reformaté pour les rendre plus lisible
avec le module sans débug on a un message utilisateur dans la page
avec module et debug on a le message utilisateur et la'exception reformatée.
A+JYT
PS : Gros merci à julien qui m'a permit de faire ça.
Hors ligne
C'est très intéressant !
Tu as fini par écrire l'article ?
Si oui, alors peux-tu mettre le lien ici ?
Si non, alors j'ai hate de le lire....
Hors ligne
J'ai une petite question concernant les codes http / headers.
Est ce que appeler $ma_reponse->setRawHeader('HTTP/1.1 404 Not Found')
équivaut à appeler $ma_reponse->setHttpResponseCode(404) ?
Merci d'avance
Hors ligne
up, siouplait ^^
Hors ligne
Hello sekaijin
Super boulot mais y a un truc que je comprend pas (bon en meme tps je suis novice sur Zend)
Si tu pouvais m'éclairer ce serait super.
Pourquoi avoir hérité d'une classe Exception_Action et non pas de Zend_Controller_Action ?
Quel est l'utilité de Fast_Debug ? est ce classe perso que tu as écrite ?
Je n'ai pas compris sont fonctionnement, si tu pouvais développer.
Par ailleurs j'utilise la classe Zend_Layout, celle ci est automatiquement appelé, est ce que quelqu'un sait comment le désactivé au niveau du controller ?
D'avance merci.
Hors ligne
Salut bucheron, pour désactiver Zend_Layout, utilise donc
Zend_Layout::getMvcInstance()->disableLayout(true);
Hors ligne
Elvis a écrit:
Salut bucheron, pour désactiver Zend_Layout, utilise donc
Code:
Zend_Layout::getMvcInstance()->disableLayout(true);
Merci Elvis
Hors ligne
Pages: 1