1 <?xml version="1.0" encoding="UTF-8"?>
3 <sect3 id="zend.controller.plugins.standard.errorhandler">
4 <title>Zend_Controller_Plugins_ErrorHandler</title>
7 <classname>Zend_Controller_Plugins_ErrorHandler</classname> представляет собой
8 плагин для обработки исключений, брошенных вашим приложением, включая
9 те, которые вызваны отсутствием запрошенного контроллера или
10 действия. Он является альтернативой способам, перечисленным в <link
11 linkend="zend.controller.exceptions">разделе об исключениях MVC</link>.
15 Основные назначения этого плагина:
21 Перехват исключений, вызванных отсутствием контроллера или
28 Перехват исключений, брошенных в контроллерах действий
34 Другими словами, плагин ErrorHandler спроектирован для обработки
35 HTTP-ошибок типа 404 (отсутствует страница) и 500
36 (внутренняя ошибка). Он не предназначен для отлова исключений,
37 сгенерированных в других плагинах или в процессе маршрутизации.
41 По умолчанию <classname>Zend_Controller_Plugins_ErrorHandler</classname> будет
43 <code>ErrorController::errorAction()</code> в модуле по умолчанию. Вы
44 можете установить альтернативные значения для перехода, используя
45 набор методов-аксессоров, доступных в плагине:
51 <code>setErrorHandlerModule()</code> устанавливает модуль, на
52 который производится переход.
58 <code>setErrorHandlerController()</code> устанавливает
59 контроллер, на который производится переход.
65 <code>setErrorHandlerAction()</code> устанавливает действие,
66 на которое производится переход.
72 <code>setErrorHandler()</code> принимает ассоциативный массив,
73 который может содержать любые из ключей 'module', 'controller'
80 Кроме этого, вы можете опционально передать конструктору
81 ассоциативный массив, который будет в свою очередь передан
82 <code>setErrorHandler()</code>.
86 <classname>Zend_Controller_Plugin_ErrorHandler</classname> регистрирует
87 перехватчик <code>postDispatch()</code> и проверяет, есть ли
88 зарегистрированые исключения в
89 <link linkend="zend.controller.response">объекте ответа</link>.
90 Если есть, то производится попытка перехода на действие,
91 зарегистрированное в качестве обработчика ошибок.
95 Если во время диспетчеризации обработчика ошибок произошло исключение,
96 то плагин скажет фронт-контроллеру, чтобы тот бросил исключения, и
97 повторно бросит последнее исключение, зарегистрированное в объекте
101 <sect4 id="zend.controller.plugins.standard.errorhandler.fourohfour">
102 <title>Использование ErrorHandler в качестве обработчика ошибки 404</title>
105 Поскольку плагин захватывает не только ошибки приложения, но и
106 ошибки в цепочке контроллеров, вызванные отсутствием класса
107 контроллера и/или метода действия, то он может использоваться в
108 качестве обработчика ошибки 404. В этом случае нужно, чтобы
109 ваш контроллер ошибок проверял тип исключения.
113 Перехваченные исключения журналируются в объекте, зарегистрированном
114 в запросе. Для его получения используйте метод
115 <code>Zend_Controller_Action::_getParam('error_handler')</code>:
118 <programlisting language="php"><![CDATA[
119 class ErrorController extends Zend_Controller_Action
121 public function errorAction()
123 $errors = $this->_getParam('error_handler');
129 Имея объект ошибки, вы можете получить тип ошибки через
130 <varname>$errors->type</varname>. Тип ошибки может быть одним из
137 <code>Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER</code>,
138 означает, что контроллер не был найден.
144 <code>Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION</code>,
145 означает, что запрошенное действие не было найдено.
151 <code>Zend_Controller_Plugin_ErrorHandler::EXCEPTION_OTHER</code>,
152 обозначает другие исключения.
158 Вы можете производить проверку на первые два типа и в случае
159 положительного ответа указывать страницу 404:
162 <programlisting language="php"><![CDATA[
163 class ErrorController extends Zend_Controller_Action
165 public function errorAction()
167 $errors = $this->_getParam('error_handler');
169 switch ($errors->type) {
170 case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER:
171 case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION:
172 // ошибка 404 - не найден контроллер или действие
174 ->setRawHeader('HTTP/1.1 404 Not Found');
176 // ... получение данных для отображения...
179 // ошибка приложения; выводим страницу ошибки,
180 // но не меняем код статуса
188 Вы можете извлекать исключение, которое инициировало вызов
189 обработчика ошибок, через свойство <code>exception</code> объекта
190 <code>error_handler</code>:
193 <programlisting language="php"><![CDATA[
194 public function errorAction()
196 $errors = $this->_getParam('error_handler');
198 switch ($errors->type) {
199 case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER:
200 case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION:
201 // ошибка 404 - не найден контроллер или действие
203 ->setRawHeader('HTTP/1.1 404 Not Found');
205 // ... получение данных для отображения...
208 // ошибка приложения; выводим страницу ошибки,
209 // но не меняем код статуса
213 // Журналируем исключение:
214 $exception = $errors->exception;
216 new Zend_Log_Writer_Stream(
217 '/tmp/applicationException.log'
220 $log->debug($exception->getMessage() . "\n" .
221 $exception->getTraceAsString());
228 <sect4 id="zend.controller.plugins.standard.errorhandler.buffer">
229 <title>Управление сгенерированным ранее выводом</title>
232 Если в процессе обработки запроса вызывается несколько действий,
233 или ваше действие несколько раз вызывает метод
234 <code>render()</code>, то возможно, что объект ответа уже содержит
235 в себе сохраненные данные для вывода. Это может привести к тому, что
236 выведется смесь из ожидаемого содержимого и содержимого
241 Если вы хотите, чтобы сообщения об ошибках выводились на этих же
242 страницах, то нет необходимости что-либо менять. В противном случае
243 следует очистить тело ответа до того, как производить рендеринг
247 <programlisting language="php"><![CDATA[
248 $this->getResponse()->clearBody();
252 <sect4 id="zend.controller.plugins.standard.errorhandler.examples">
253 <title>Примеры использования плагина</title>
255 <example id="zend.controller.plugins.standard.errorhandler.examples.example-1">
256 <title>Стандартное использование</title>
257 <programlisting language="php"><![CDATA[
258 $front = Zend_Controller_Front::getInstance();
259 $front->registerPlugin(new Zend_Controller_Plugin_ErrorHandler());
263 <example id="zend.controller.plugins.standard.errorhandler.examples.example-2">
264 <title>Установка другого обработчика ошибок</title>
265 <programlisting language="php"><![CDATA[
266 $front = Zend_Controller_Front::getInstance();
267 $front->registerPlugin(new Zend_Controller_Plugin_ErrorHandler(array(
268 'module' => 'mystuff',
269 'controller' => 'static',
275 <example id="zend.controller.plugins.standard.errorhandler.examples.example-3">
276 <title>Использование аксессоров</title>
277 <programlisting language="php"><![CDATA[
278 $plugin = new Zend_Controller_Plugin_ErrorHandler();
279 $plugin->setErrorHandlerModule('mystuff')
280 ->setErrorHandlerController('static')
281 ->setErrorHandlerAction('error');
283 $front = Zend_Controller_Front::getInstance();
284 $front->registerPlugin($plugin);
290 <sect4 id="zend.controller.plugins.standard.errorhandler.controllerexamples">
291 <title>Пример контроллера ошибок</title>
294 Для того, чтобы использовать плагин ErrorHandler, нужен контроллер
295 ошибок. Ниже приводится простой пример такого контроллера.
298 <programlisting language="php"><![CDATA[
299 class ErrorController extends Zend_Controller_Action
301 public function errorAction()
303 $errors = $this->_getParam('error_handler');
305 switch ($errors->type) {
306 case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER:
307 case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION:
308 // ошибка 404 - не найден контроллер или действие
309 $this->getResponse()->setRawHeader('HTTP/1.1 404 Not Found');
313 <p>Запрошенная вами страница не найдена.</p>
320 <p>Произошла непредвиденная ошибка. Пожалуйста, попробуйте позднее.</p>
325 // Удаление добавленного ранее содержимого
326 $this->getResponse()->clearBody();
328 $this->view->content = $content;