2012-02-04 3 views
4

У меня есть модуль Api, где я пытаюсь реализовать RESTful API. Проблема в том, что когда я делаю исключение в этом модуле, я хотел бы, чтобы исключение было выбрано и не обработано контроллером ошибок в модуле по умолчанию.Как отключить контроллер ошибок для определенного модуля

Можно ли отключить контроллер ошибок только для определенного модуля в Zend Framework?

ответ

4

Используя следующий метод, вы можете отключить обработчик ошибок для определенного модуля. В этом примере я назову ваш модуль RESTful rest.

Во-первых, создайте новый плагин в своем приложении. Например, это будет Application_Plugin_RestErrorHandler. Добавьте следующий код application/plugins/RestErrorHandler.php

class Application_Plugin_RestErrorHandler extends Zend_Controller_Plugin_Abstract 
{ 
    public function preDispatch(Zend_Controller_Request_Abstract $request) 
    { 
     $module = $request->getModuleName(); 

     // don't run this plugin unless we are in the rest module 
     if ($module != 'rest') return ; 

     // disable the error handler, this has to be done prior to dispatch() 
     Zend_Controller_Front::getInstance()->setParam('noErrorHandler', true); 
    } 
} 

Далее в модуле Bootstrap для rest модуля, мы будем регистрировать плагин. Это находится в modules/rest/Bootstrap.php. Так как все модульные бутстрапы выполняются независимо от текущего модуля, он может попасть в ваш основной загрузочный файл, но мне нравится регистрировать плагины, связанные с определенным модулем в загрузочном модуле этого модуля.

protected function _initPlugins() 
{ 
    $bootstrap = $this->getApplication(); 
    $bootstrap->bootstrap('frontcontroller'); 
    $front = $bootstrap->getResource('frontcontroller'); 

    // register the plugin 
    $front->registerPlugin(new Application_Plugin_RestErrorHandler()); 
} 

Другая возможность - сохранить обработчик ошибок, но использовать обработчик ошибок, специфичный для модуля. Таким образом, обработчик ошибок для вашего модуля rest может вести себя по-разному и выводить дружественную ошибку REST.

Для этого скопируйте ErrorController.php в modules/rest/controllers/ErrorController.php и переименуйте класс в Rest_ErrorController. Затем скопируйте сценарий представления для контроллера ошибок на modules/rest/views/scripts/error/error.phtml.

Настроить error.phtml по своему вкусу, чтобы сообщение об ошибке использовало тот же формат JSON/XML, который используется вашим модулем отдыха.

Затем мы сделаем небольшую настройку для плагина выше. Что мы сделаем, так это сказать Zend_Controller_Front использовать ErrorController :: errorAction из модуля rest вместо модуля по умолчанию. Если бы вы хотели, вы могли бы использовать другой контроллер, чем ErrorController. Измените плагин выглядеть следующим образом:

class Application_Plugin_RestErrorHandler extends Zend_Controller_Plugin_Abstract 
{ 
    public function preDispatch(Zend_Controller_Request_Abstract $request) 
    { 
     $module = $request->getModuleName(); 

     if ($module != 'rest') return ; 

     $errorHandler = Zend_Controller_Front::getInstance() 
         ->getPlugin('Zend_Controller_Plugin_ErrorHandler'); 

     // change the error handler being used from the one in the default module, to the one in the rest module 
     $errorHandler->setErrorHandlerModule($module); 
    } 
} 

с описанным выше способом, вам все равно необходимо зарегистрировать плагин в Bootstrap.

Надеюсь, что это поможет.

+0

Спасибо, это очень помогло мне. Я хочу просто отобразить ошибку XML-ответа при вызове исключения. –

+0

В этом случае я думаю, что вы хотите использовать второй метод. В противном случае исключение будет полностью возвращено на передний контроллер и с отключенной обработкой ошибок. Я думаю, что в конечном итоге вы получите отказ от возврата к PHP, а в производственной среде вы обычно просто закончите с ошибкой 500 серверов. Если вы настроите обработчик ошибок для модуля, вы можете иметь возможность зарегистрировать исключение контроллера, если оно не вызвано фиктивным пользовательским вводом, а сценарий просмотра ошибок может просто безоговорочно показать ответ XML, представляющий состояние ошибки. – drew010

+0

Просто подумал об этом немного больше, вы все равно можете использовать обработчик ошибок по умолчанию из модуля по умолчанию, просто назначьте текущий модуль представлению из ErrorController и либо покажите XML, когда модуль будет отдыхать, либо вы можете получить ошибку контроллер render error.xml.phtml или что-то в этом роде. – drew010