Zend_Controller-Plugins-ErrorHandler.xml 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- Reviewed: no -->
  3. <sect3 id="zend.controller.plugins.standard.errorhandler">
  4. <title>Zend_Controller_Plugins_ErrorHandler</title>
  5. <para>
  6. <classname>Zend_Controller_Plugins_ErrorHandler</classname> представляет собой
  7. плагин для обработки исключений, брошенных вашим приложением, включая
  8. те, которые вызваны отсутствием запрошенного контроллера или
  9. действия. Он является альтернативой способам, перечисленным в <link
  10. linkend="zend.controller.exceptions">разделе об исключениях MVC</link>.
  11. </para>
  12. <para>
  13. Основные назначения этого плагина:
  14. </para>
  15. <itemizedlist>
  16. <listitem>
  17. <para>
  18. Перехват исключений, вызванных отсутствием контроллера или
  19. метода действия
  20. </para>
  21. </listitem>
  22. <listitem>
  23. <para>
  24. Перехват исключений, брошенных в контроллерах действий
  25. </para>
  26. </listitem>
  27. </itemizedlist>
  28. <para>
  29. Другими словами, плагин ErrorHandler спроектирован для обработки
  30. HTTP-ошибок типа 404 (отсутствует страница) и 500
  31. (внутренняя ошибка). Он не предназначен для отлова исключений,
  32. сгенерированных в других плагинах или в процессе маршрутизации.
  33. </para>
  34. <para>
  35. По умолчанию <classname>Zend_Controller_Plugins_ErrorHandler</classname> будет
  36. производить переход к
  37. <code>ErrorController::errorAction()</code> в модуле по умолчанию. Вы
  38. можете установить альтернативные значения для перехода, используя
  39. набор методов-аксессоров, доступных в плагине:
  40. </para>
  41. <itemizedlist>
  42. <listitem>
  43. <para>
  44. <code>setErrorHandlerModule()</code> устанавливает модуль, на
  45. который производится переход.
  46. </para>
  47. </listitem>
  48. <listitem>
  49. <para>
  50. <code>setErrorHandlerController()</code> устанавливает
  51. контроллер, на который производится переход.
  52. </para>
  53. </listitem>
  54. <listitem>
  55. <para>
  56. <code>setErrorHandlerAction()</code> устанавливает действие,
  57. на которое производится переход.
  58. </para>
  59. </listitem>
  60. <listitem>
  61. <para>
  62. <code>setErrorHandler()</code> принимает ассоциативный массив,
  63. который может содержать любые из ключей 'module', 'controller'
  64. или 'action'.
  65. </para>
  66. </listitem>
  67. </itemizedlist>
  68. <para>
  69. Кроме этого, вы можете опционально передать конструктору
  70. ассоциативный массив, который будет в свою очередь передан
  71. <code>setErrorHandler()</code>.
  72. </para>
  73. <para>
  74. <classname>Zend_Controller_Plugin_ErrorHandler</classname> регистрирует
  75. перехватчик <code>postDispatch()</code> и проверяет, есть ли
  76. зарегистрированые исключения в
  77. <link linkend="zend.controller.response">объекте ответа</link>.
  78. Если есть, то производится попытка перехода на действие,
  79. зарегистрированное в качестве обработчика ошибок.
  80. </para>
  81. <para>
  82. Если во время диспетчеризации обработчика ошибок произошло исключение,
  83. то плагин скажет фронт-контроллеру, чтобы тот бросил исключения, и
  84. повторно бросит последнее исключение, зарегистрированное в объекте
  85. ответа.
  86. </para>
  87. <sect4 id="zend.controller.plugins.standard.errorhandler.fourohfour">
  88. <title>Использование ErrorHandler в качестве обработчика ошибки 404</title>
  89. <para>
  90. Поскольку плагин захватывает не только ошибки приложения, но и
  91. ошибки в цепочке контроллеров, вызванные отсутствием класса
  92. контроллера и/или метода действия, то он может использоваться в
  93. качестве обработчика ошибки 404. В этом случае нужно, чтобы
  94. ваш контроллер ошибок проверял тип исключения.
  95. </para>
  96. <para>
  97. Перехваченные исключения журналируются в объекте, зарегистрированном
  98. в запросе. Для его получения используйте метод
  99. <code>Zend_Controller_Action::_getParam('error_handler')</code>:
  100. </para>
  101. <programlisting language="php"><![CDATA[
  102. class ErrorController extends Zend_Controller_Action
  103. {
  104. public function errorAction()
  105. {
  106. $errors = $this->_getParam('error_handler');
  107. }
  108. }
  109. ]]></programlisting>
  110. <para>
  111. Имея объект ошибки, вы можете получить тип ошибки через
  112. <varname>$errors->type</varname>. Тип ошибки может быть одним из
  113. следующих:
  114. </para>
  115. <itemizedlist>
  116. <listitem>
  117. <para>
  118. <code>Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER</code>,
  119. означает, что контроллер не был найден.
  120. </para>
  121. </listitem>
  122. <listitem>
  123. <para>
  124. <code>Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION</code>,
  125. означает, что запрошенное действие не было найдено.
  126. </para>
  127. </listitem>
  128. <listitem>
  129. <para>
  130. <code>Zend_Controller_Plugin_ErrorHandler::EXCEPTION_OTHER</code>,
  131. обозначает другие исключения.
  132. </para>
  133. </listitem>
  134. </itemizedlist>
  135. <para>
  136. Вы можете производить проверку на первые два типа и в случае
  137. положительного ответа указывать страницу 404:
  138. </para>
  139. <programlisting language="php"><![CDATA[
  140. class ErrorController extends Zend_Controller_Action
  141. {
  142. public function errorAction()
  143. {
  144. $errors = $this->_getParam('error_handler');
  145. switch ($errors->type) {
  146. case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER:
  147. case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION:
  148. // ошибка 404 - не найден контроллер или действие
  149. $this->getResponse()
  150. ->setRawHeader('HTTP/1.1 404 Not Found');
  151. // ... получение данных для отображения...
  152. break;
  153. default:
  154. // ошибка приложения; выводим страницу ошибки,
  155. // но не меняем код статуса
  156. break;
  157. }
  158. }
  159. }
  160. ]]></programlisting>
  161. <para>
  162. Вы можете извлекать исключение, которое инициировало вызов
  163. обработчика ошибок, через свойство <code>exception</code> объекта
  164. <code>error_handler</code>:
  165. </para>
  166. <programlisting language="php"><![CDATA[
  167. public function errorAction()
  168. {
  169. $errors = $this->_getParam('error_handler');
  170. switch ($errors->type) {
  171. case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER:
  172. case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION:
  173. // ошибка 404 - не найден контроллер или действие
  174. $this->getResponse()
  175. ->setRawHeader('HTTP/1.1 404 Not Found');
  176. // ... получение данных для отображения...
  177. break;
  178. default:
  179. // ошибка приложения; выводим страницу ошибки,
  180. // но не меняем код статуса
  181. // ...
  182. // Журналируем исключение:
  183. $exception = $errors->exception;
  184. $log = new Zend_Log(
  185. new Zend_Log_Writer_Stream(
  186. '/tmp/applicationException.log'
  187. )
  188. );
  189. $log->debug($exception->getMessage() . "\n" .
  190. $exception->getTraceAsString());
  191. break;
  192. }
  193. }
  194. ]]></programlisting>
  195. </sect4>
  196. <sect4 id="zend.controller.plugins.standard.errorhandler.buffer">
  197. <title>Управление сгенерированным ранее выводом</title>
  198. <para>
  199. Если в процессе обработки запроса вызывается несколько действий,
  200. или ваше действие несколько раз вызывает метод
  201. <code>render()</code>, то возможно, что объект ответа уже содержит
  202. в себе сохраненные данные для вывода. Это может привести к тому, что
  203. выведется смесь из ожидаемого содержимого и содержимого
  204. ошибки.
  205. </para>
  206. <para>
  207. Если вы хотите, чтобы сообщения об ошибках выводились на этих же
  208. страницах, то нет необходимости что-либо менять. В противном случае
  209. следует очистить тело ответа до того, как производить рендеринг
  210. каких-либо видов:
  211. </para>
  212. <programlisting language="php"><![CDATA[
  213. $this->getResponse()->clearBody();
  214. ]]></programlisting>
  215. </sect4>
  216. <sect4 id="zend.controller.plugins.standard.errorhandler.examples">
  217. <title>Примеры использования плагина</title>
  218. <example id="zend.controller.plugins.standard.errorhandler.examples.example-1">
  219. <title>Стандартное использование</title>
  220. <programlisting language="php"><![CDATA[
  221. $front = Zend_Controller_Front::getInstance();
  222. $front->registerPlugin(new Zend_Controller_Plugin_ErrorHandler());
  223. ]]></programlisting>
  224. </example>
  225. <example id="zend.controller.plugins.standard.errorhandler.examples.example-2">
  226. <title>Установка другого обработчика ошибок</title>
  227. <programlisting language="php"><![CDATA[
  228. $front = Zend_Controller_Front::getInstance();
  229. $front->registerPlugin(new Zend_Controller_Plugin_ErrorHandler(array(
  230. 'module' => 'mystuff',
  231. 'controller' => 'static',
  232. 'action' => 'error'
  233. )));
  234. ]]></programlisting>
  235. </example>
  236. <example id="zend.controller.plugins.standard.errorhandler.examples.example-3">
  237. <title>Использование аксессоров</title>
  238. <programlisting language="php"><![CDATA[
  239. $plugin = new Zend_Controller_Plugin_ErrorHandler();
  240. $plugin->setErrorHandlerModule('mystuff')
  241. ->setErrorHandlerController('static')
  242. ->setErrorHandlerAction('error');
  243. $front = Zend_Controller_Front::getInstance();
  244. $front->registerPlugin($plugin);
  245. ]]>
  246. </programlisting>
  247. </example>
  248. </sect4>
  249. <sect4 id="zend.controller.plugins.standard.errorhandler.controllerexamples">
  250. <title>Пример контроллера ошибок</title>
  251. <para>
  252. Для того, чтобы использовать плагин ErrorHandler, нужен контроллер
  253. ошибок. Ниже приводится простой пример такого контроллера.
  254. </para>
  255. <programlisting language="php"><![CDATA[
  256. class ErrorController extends Zend_Controller_Action
  257. {
  258. public function errorAction()
  259. {
  260. $errors = $this->_getParam('error_handler');
  261. switch ($errors->type) {
  262. case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER:
  263. case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION:
  264. // ошибка 404 - не найден контроллер или действие
  265. $this->getResponse()->setRawHeader('HTTP/1.1 404 Not Found');
  266. $content =<<<EOH
  267. <h1>Ошибка!</h1>
  268. <p>Запрошенная вами страница не найдена.</p>
  269. EOH;
  270. break;
  271. default:
  272. // ошибка приложения
  273. $content =<<<EOH
  274. <h1>Ошибка!</h1>
  275. <p>Произошла непредвиденная ошибка. Пожалуйста, попробуйте позднее.</p>
  276. EOH;
  277. break;
  278. }
  279. // Удаление добавленного ранее содержимого
  280. $this->getResponse()->clearBody();
  281. $this->view->content = $content;
  282. }
  283. }
  284. ]]></programlisting>
  285. </sect4>
  286. </sect3>
  287. <!--
  288. vim:se ts=4 sw=4 et:
  289. -->