Programmer's Reference Guide
| Utilisation de conventions de dossiers modulaires |
Exceptions avec MVC
Introduction
Les composants MVC de Zend Framework utilisent un contrôleur frontal, ce qui veut dire que toute requête envoyée à l'application entre sur ce point unique. Ainsi, toutes les exceptions sont encapsulées dans le contrôleur frontal, ceci vous permet de toutes les traiter dans un seul endroit.
Cependant, les exceptions peuvent contenir des messages ou des traces
plutôt sensibles pour le système, comme des requêtes SQL, l'emplacement
de certains fichiers ... Pour vous aider à protéger votre site, par défaut,
Zend_Controller_Front attrape toutes les exceptions et les enregistre
dans l'objet de réponse; et bien entendu, par défaut, cet objet de réponse
n'affiche pas ces exceptions.
Comment gérer les exceptions?
Plusieurs mécanismes vont vous permettre de traiter les exceptions dans le modèle MVC de ZendFramework.
-
Par défaut, le pluginerror handler est présent, et activé. Ce plugin a été conçu pour gérer:
Les erreurs d'absence de contrôleurs ou d'actions
Erreurs survenant dans un contrôleur
Error handler agit dans le
postDispatch(), et analyse si une exception a été levée(en gérant son type). Si c'est le cas, alors le plugin renvoie un jeton vers un contrôleur de gestion des erreurs.Ce contrôleurs couvrira la majorité des cas d'utilisation. Il parvient à gérer les cas 'contrôleur absent', 'action absente', ou 'autre cas'.
-
Zend_Controller_Front::throwExceptions()En passant la valeur true à cette méthode, vous indiquez au contrôleur frontal que vous souhaitez qu'il vous retourne les exceptions qu'il rencontre. Ainsi, il ne les ajoutera pas à la réponse, et il ne fera pas intervenir le plugin 'Error handler'. Exemple:
<?php $front->throwExceptions(true); try { $front->dispatch(); } catch (Exception $e) { // A vous de gérer ici }?>Cette méthode vous permet d'utiliser une gestion personnalisée des exceptions dans votre application, de manière simple.
-
Zend_Controller_Response_Abstract::renderExceptions()En passant un paramètre true à cette méthode, vous indiquez à la réponse d'afficher les exceptions qu'elle reçoit (du contrôleur frontal, ou du plugin 'Error handler', par exemple), lorsque son rendu est appelé. Ceci ne devrait être activé qu'en environnement de développement.
-
Zend_Controller_Front::returnResponse()etZend_Controller_Response_Abstract::isException().En passant le booléen true à
Zend_Controller_Front::returnResponse(),Zend_Controller_Front::dispatch()ne commandera pas l'affichage de la réponse automatiquement. Au lieu de cela, l'objet de réponse sera retourné. Vous pouvez alors tester celui-ci pour voir s'il contient des exceptions, ceci grâce àisException()etgetException(). Voyez:<?php $front->returnResponse(true); $response = $front->dispatch(); if ($response->isException()) { $exceptions = $response->getException(); // Gestion des exceptions ici } else { $response->sendHeaders(); $response->outputBody(); }?>Par rapport à
Zend_Controller_Front::throwExceptions(), cette utilisation vous permet de ne rendre la réponse que lorsque vous le décidez, selon la présence de telle ou telle exception, ou pas.
Différents types d'exceptions que vous pouvez rencontrer
Les composants MVC sont nombreux, -- requête, routeur, dispatcheur, contrôleur, et response -- chaque objet risque de renvoyer une exception qui lui est propre. Certaines peuvent être créees ou dérivées, d'autres par défaut indiquent un problème de l'application.
Comme exemples :
-
Zend_Controller_Dispatcher::dispatch()va envoyer une exception, par défaut, si un contrôleur invalide est demandé. Vous pouvez jouer sur ce paramètre :-
Initialisez le paramètre
useDefaultControllerAlwaysDans votre contrôleur frontal, ou dispatcheur, ajoutez la directive suivante :
<?php $front->setParam('useDefaultControllerAlways', true); // ou $dispatcher->setParam('useDefaultControllerAlways', true);?>Lorsque ceci est injecté, le dispatcheur utilisera le contrôleur par défaut s'il s'aperçoit qu'il ne peut dispatcher un contrôleur spécifique, plutôt que de renvoyer une exception. Méfiez vous des moteurs de recherche qui n'aiment pas que plusieurs URI pointent sur un même contenu. En effet, avec ce pramètre activé, les utilisateurs orthographiant mal votre site, seront redirigés vers la page d'accueil de celui-ci, ce qui peut aboutir à du 'duplicate content'.
-
L'exception envoyée par
dispatch()est de typeZend_Controller_Dispatcher_Exceptionet contient le message 'Invalid controller specified'. Utlisez une méthode comme vue dans la section précédente pour attraper celle-ci et rediriger vers une page d'erreur générique.
-
-
Zend_Controller_Action::__call()enverra uneZend_Controller_Action_Exceptionsi il n'est pas possible de dispatcher l'action demandée. Il est facile de changer ce comportement :-
Dérivez la classe
Zend_Controller_Actionen redéfinissant sa méthode__call()method, voyez plutôt :<?php class My_Controller_Action extends Zend_Controller_Action { public function __call($method, $args) { if ('Action' == substr($method, -6)) { $controller = $this->getRequest()->getControllerName(); $url = '/' . $controller . '/index'; return $this->_redirect($url); } throw new Exception('Invalid method'); } }?>Cet exemple intercepte les actions non existantes, et redirige vers l'action principale du contrôleur actuel.
-
Dérivez
Zend_Controller_Dispatcheret rédéfinissezgetAction()pour vérifier si l'action existe bien :<?php class My_Controller_Dispatcher extends Zend_Controller_Dispatcher { public function getAction($request) { $action = $request->getActionName(); if (empty($action)) { $action = $this->getDefaultAction(); $request->setActionName($action); $action = $this->formatActionName($action); } else { $controller = $this->getController(); $action = $this->formatActionName($action); if (!method_exists($controller, $action)) { $action = $this->getDefaultAction(); $request->setActionName($action); $action = $this->formatActionName($action); } } return $action; } }?>L'exemple précédant vérifie si l'action existe dans le contrôleur demandé. Si ce n'est pas le cas, il redéfinit l'action en spécifiant celle par défaut.
Cette méthode permet de changer l'action avant le dispatching. Attention une fois encore aux erreurs de syntaxes dans l'URL, qui devraient mener vers une page d'erreur quelconque.
-
Utilisez
Zend_Controller_Action::preDispatch()ouZend_Controller_Plugin_Abstract::preDispatch()pour identifier les actions invalides.En dérivant
Zend_Controller_Actionpour y modifierpreDispatch(), vous agissez sur la globalité de vos contrôleurs, avant même le dispatching de l'action demandée.L'utilisation d'un plugin offre une fléxibilité supplémentaire : Si tous vos contrôleurs n'héritent pas de la même classe, plutôt que de dupliquer du code, un plugin va agir indépendament de vos contrôleurs. En preDispatch(), il agit avant ceux-ci.
Par exemple :
<?php class My_Controller_PreDispatchPlugin extends Zend_Controller_Plugin_Abstract { public function preDispatch(Zend_Controller_Request_Abstract $request) { $dispatcher = Zend_Controller_Front::getInstance()->getDispatcher(); $controller = $dispatcher->getController($request); if (!$controller) { $controller = $dispatcher->getDefaultControllerName($request); } $action = $dispatcher->getAction($request); if (!method_exists($controller, $action)) { $defaultAction = $dispatcher->getDefaultAction(); $controllerName = $request->getControllerName(); $response = Zend_Controller_Front::getInstance()->getResponse(); $response->setRedirect('/' . $controllerName . '/' . $defaultAction); $response->sendHeaders(); exit; } } }?>Dans cet exemple, nous vérifions si l'action demandée existe dans le contrôleur dispatché. Si ce n'est pas le cas, nous executons une redirection immédiate.
-
| Utilisation de conventions de dossiers modulaires |
Select a Version
Languages Available
Components
Search the Manual
Navigation
- Guide de référence du programmeur
- Guide de référence du programmeur
- Zend_Controller
- Zend_Controller - Démarrage rapide
- Fondations de Zend_Controller
- Le contrôleur frontal (Front Controller)
- L'objet Requête
- Routeur Standard : Zend_Controller_Router_Rewrite
- Le dispatcheur
- Contrôleurs d'action
- Aides d'action (Helper)
- Objet de réponse
- Plugins
- Utilisation de conventions de dossiers modulaires
- Exceptions avec MVC
- Migrer depuis des versions précédentes
