Zend_Controller-Plugins-ErrorHandler.xml 15 KB

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