Zend_Controller-Plugins-ErrorHandler.xml 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <!-- EN-Revision: 17175 -->
  3. <!-- Reviewed: no -->
  4. <sect3 id="zend.controller.plugins.standard.errorhandler">
  5. <title>Zend_Controller_Plugin_ErrorHandler</title>
  6. <para>
  7. <classname>Zend_Controller_Plugin_ErrorHandler</classname> est un plugin intégré
  8. d'office dans le modèle <acronym>MVC</acronym>, il sert à gérer les exceptions envoyées par l'application, en
  9. particulier celles concernant des contrôleurs ou des actions manquants. C'est une manière
  10. rejoignant la section
  11. <link linkend="zend.controller.exceptions">Exceptions <acronym>MVC</acronym></link>.
  12. </para>
  13. <para>Les principaux objectifs de ce plugin sont&#160;:</para>
  14. <itemizedlist>
  15. <listitem>
  16. <para>
  17. Intercepter les exceptions envoyées si un contrôleur ou une action ne peuvent
  18. être trouvés
  19. </para>
  20. </listitem>
  21. <listitem>
  22. <para>Intercepte les exceptions envoyées dans les contrôleurs</para>
  23. </listitem>
  24. </itemizedlist>
  25. <para>
  26. Globalement, <code>ErrorHandler</code> sert à gérer les erreurs 404 ou 500.
  27. Attention, le plugin n'est pas destiné à intervenir sur les exceptions envoyées dans
  28. d'autres plugins. Des effets de bords peuvent apparaître, veillez à les gérer.
  29. </para>
  30. <para>
  31. Par défaut, <classname>Zend_Controller_Plugin_ErrorHandler</classname> redirige vers
  32. <methodname>ErrorController::errorAction()</methodname> dans le module par défaut. Vous pouvez passer
  33. d'autres valeurs via les accesseurs du plugin&#160;:
  34. </para>
  35. <itemizedlist>
  36. <listitem>
  37. <para><methodname>setErrorHandlerModule()</methodname> définit le module à utiliser.</para>
  38. </listitem>
  39. <listitem>
  40. <para>
  41. <methodname>setErrorHandlerController()</methodname> définit le contrôleur à
  42. utiliser.
  43. </para>
  44. </listitem>
  45. <listitem>
  46. <para><methodname>setErrorHandlerAction()</methodname> définit l'action à utiliser.</para>
  47. </listitem>
  48. <listitem>
  49. <para>
  50. <methodname>setErrorHandler()</methodname> est un raccourci des trois précédantes. Passez
  51. un tableau avec les clés "module", "controller", or "action", et leurs valeurs
  52. appropriées.
  53. </para>
  54. </listitem>
  55. </itemizedlist>
  56. <para>
  57. Ce comportement fonctionne aussi avec le constructeur du plugin. Celui-ci agit comme
  58. un proxy vers <methodname>setErrorHandler()</methodname>.
  59. </para>
  60. <para>
  61. <classname>Zend_Controller_Plugin_ErrorHandler</classname> agit en
  62. <methodname>postDispatch()</methodname> et analyse
  63. <link linkend="zend.controller.response">l'objet de réponse</link>à la recherche
  64. d'éventuelles exceptions. Si il y en a, alors le plugin modifie la requête pour distribuer
  65. le contrôleur et l'action d'erreur.
  66. </para>
  67. <para>
  68. Si une exception arrive lorsque le plugin agit, alors celui-ci ordonne au contrôleur
  69. frontal de renvoyer l'exception. C'est pour cela qu'il faudrait systématiquement entourer
  70. sa méthode <code>dispatch</code>, du contrôleur frontal&#160;; d'un bloc <code>try /
  71. catch</code>.
  72. </para>
  73. <sect4 id="zend.controller.plugins.standard.errorhandler.fourohfour">
  74. <title>Utilisation de ErrorHandler pour gérer les erreurs 404</title>
  75. <para>
  76. Comme <code>ErrorHandler</code> capture les exceptions relatives à un problème de
  77. contrôleur ou action manquants, vous pouvez donc l'utiliser comme un gestionnaire
  78. d'erreurs 404. Pour cela, il faut analyser le type d'exception ayant mené à
  79. l'erreur.
  80. </para>
  81. <para>
  82. Les exceptions capturées sont enregistrées en tant que paramètre d'action.
  83. <methodname>Zend_Controller_Action::_getParam('error_handler')</methodname>:
  84. </para>
  85. <programlisting language="php"><![CDATA[
  86. class ErrorController extends Zend_Controller_Action
  87. {
  88. public function errorAction()
  89. {
  90. $errors = $this->_getParam('error_handler');
  91. }
  92. }
  93. ]]></programlisting>
  94. <para>
  95. Une fois que vous possédez l'objet contenant l'exception, inspectez son type avec
  96. <code>$errors-&gt;type</code>. Des constantes sont à votre disposition&#160;:
  97. </para>
  98. <itemizedlist>
  99. <listitem>
  100. <para>
  101. <classname>Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER</classname>,
  102. indique un contrôleur non trouvé.
  103. </para>
  104. </listitem>
  105. <listitem>
  106. <para>
  107. <classname>Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION</classname>,
  108. indique qu'une action est absente.
  109. </para>
  110. </listitem>
  111. <listitem>
  112. <para>
  113. <classname>Zend_Controller_Plugin_ErrorHandler::EXCEPTION_OTHER</classname>,
  114. indique une autre exception.
  115. </para>
  116. </listitem>
  117. </itemizedlist>
  118. <para>Les deux premiers types pourraient mener à une erreur 404&#160;:</para>
  119. <programlisting language="php"><![CDATA[
  120. class ErrorController extends Zend_Controller_Action
  121. {
  122. public function errorAction()
  123. {
  124. $errors = $this->_getParam('error_handler');
  125. switch ($errors->type) {
  126. case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER:
  127. case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION:
  128. // erreur 404 -- contrôleur ou action introuvable
  129. $this->getResponse()->setRawHeader('HTTP/1.1 404 Not Found');
  130. // ... ici, de l'affichage (du rendu)
  131. break;
  132. default:
  133. // erreur applicative; affiche une page d'erreur,
  134. // mais sans changer le code de retour HTTP
  135. break;
  136. }
  137. }
  138. }
  139. ]]></programlisting>
  140. <para>
  141. Enfin, il est possible de récupérer l'exception ayant menée au contrôleur
  142. d'erreur. Ceci afin de l'analyser. L'attribut <code>exception</code> de l'objet le
  143. permet&#160;:
  144. </para>
  145. <programlisting language="php"><![CDATA[
  146. public function errorAction()
  147. {
  148. $errors = $this->_getParam('error_handler');
  149. switch ($errors->type) {
  150. case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER:
  151. case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION:
  152. // erreur 404 -- contrôleur ou action introuvable
  153. $this->getResponse()->setRawHeader('HTTP/1.1 404 Not Found');
  154. // ... ici, de l'affichage (du rendu)
  155. break;
  156. default:
  157. // erreur applicative; affiche une page d'erreur,
  158. // mais sans changer le code de retour HTTP
  159. // ...
  160. // Sauve l'exception en log:
  161. $exception = $errors->exception;
  162. $log =
  163. new Zend_Log(
  164. new Zend_Log_Writer_Stream(
  165. '/tmp/applicationException.log')
  166. );
  167. $log->debug($exception->getMessage()
  168. . "\n"
  169. . $exception->getTraceAsString());
  170. break;
  171. }
  172. }
  173. ]]></programlisting>
  174. </sect4>
  175. <sect4 id="zend.controller.plugins.standard.errorhandler.buffer">
  176. <title>Gestion des rendus précédants de la réponse</title>
  177. <para>
  178. Si vous décomposez vos processus en plusieurs actions ou plusieurs appels à
  179. <methodname>render()</methodname>, il est possible que la réponse contienne déjà des éléments
  180. lorsque <code>ErrorHandler</code> agit.
  181. </para>
  182. <para>
  183. Si vous désirez rendre votre contrôleur d'erreur dans ce contenu, alors il n'y a
  184. rien à faire de spécial. En revanche, il peut aussi être judicieux de vider totalement
  185. la réponse afin de rendre le contrôleur d'erreurs. Procédez alors comme suit&#160;:
  186. </para>
  187. <programlisting language="php"><![CDATA[
  188. $this->getResponse()->clearBody();
  189. ]]></programlisting>
  190. </sect4>
  191. <sect4 id="zend.controller.plugins.standard.errorhandler.examples">
  192. <title>Exemples d'utilisation</title>
  193. <example id="zend.controller.plugins.standard.errorhandler.examples.example-1">
  194. <title>Utilisation standard et désactivation</title>
  195. <programlisting language="php"><![CDATA[
  196. $front = Zend_Controller_Front::getInstance();
  197. $front->registerPlugin(new Zend_Controller_Plugin_ErrorHandler());
  198. ]]></programlisting>
  199. </example>
  200. <para>
  201. Notez bien que l'exemple ci-dessus ne sert pas à grand chose : le plugin
  202. <code>ErrorHandler</code> est actif par défaut, dans le contrôleur frontal. Il est
  203. cependant possible de le désactiver, passez un paramètre au contrôleur frontal&#160;:
  204. </para>
  205. <programlisting language="php"><![CDATA[
  206. $front = Zend_Controller_Front::getInstance();
  207. $front->setParam('noErrorHandler',true);
  208. ]]></programlisting>
  209. <example id="zend.controller.plugins.standard.errorhandler.examples.example-2">
  210. <title>Paramétrage du plugin</title>
  211. <programlisting language="php"><![CDATA[
  212. $front = Zend_Controller_Front::getInstance();
  213. $front->registerPlugin(new Zend_Controller_Plugin_ErrorHandler(array(
  214. 'module' => 'mystuff',
  215. 'controller' => 'static',
  216. 'action' => 'error'
  217. )));
  218. ]]></programlisting>
  219. </example>
  220. <example id="zend.controller.plugins.standard.errorhandler.examples.example-3">
  221. <title>Utilisation des accesseurs</title>
  222. <programlisting language="php"><![CDATA[
  223. $plugin = new Zend_Controller_Plugin_ErrorHandler();
  224. $plugin->setErrorHandlerModule('mystuff')
  225. ->setErrorHandlerController('static')
  226. ->setErrorHandlerAction('error');
  227. $front = Zend_Controller_Front::getInstance();
  228. $front->registerPlugin($plugin);
  229. ]]></programlisting>
  230. </example>
  231. </sect4>
  232. <sect4 id="zend.controller.plugins.standard.errorhandler.controllerexamples">
  233. <title>Exemple de contrôleur d'erreurs</title>
  234. <para>
  235. Pour utiliser le plugin <code>ErrorHandler</code>, un contrôleur d'erreurs est
  236. requis. En voici un exemple&#160;:
  237. </para>
  238. <programlisting language="php"><![CDATA[
  239. class ErrorController extends Zend_Controller_Action
  240. {
  241. public function errorAction()
  242. {
  243. $errors = $this->_getParam('error_handler');
  244. switch ($errors->type) {
  245. case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER:
  246. case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION:
  247. // 404 error -- controller or action not found
  248. $this->getResponse()->setRawHeader('HTTP/1.1 404 Not Found');
  249. $content =<<<EOH
  250. <h1>Erreur !</h1>
  251. <p>Page introuvable.</p>
  252. EOH;
  253. break;
  254. default:
  255. // application error
  256. $content =<<<EOH
  257. <h1>Erreur !</h1>
  258. <p>Une erreur innatendue est survenue</p>
  259. EOH;
  260. break;
  261. }
  262. // Vide le contenu de la réponse
  263. $this->getResponse()->clearBody();
  264. $this->view->content = $content;
  265. }
  266. }
  267. ]]></programlisting>
  268. </sect4>
  269. </sect3>