Я использую ErrorController
, созданный для меня Zend Tool. Самое первое, что делает мой файл index.php
, – это зарегистрировать обработчик ошибок, который преобразует ошибки и предупреждения в исключения:
function handleError($errno, $errstr, $errfile, $errline, array $errcontext) { // error was suppressed with the @-operator if (0 === error_reporting()) { return false; } throw new ErrorException($errstr, 0, $errno, $errfile, $errline); } set_error_handler('handleError');
У меня также есть это в index.php
:
$front = Zend_Controller_Front::getInstance(); $front->throwExceptions(false);
Проблема в том, что он не обрабатывает исключения, которые поступают из файла Bootstrap. Исключение срабатывает, но ErrorController
не получает его. Выполнение страницы просто останавливается, и никакие представления не отображаются.
Как я могу маршрутизировать все исключения и предупреждения через контроллер ошибок (за исключением синтаксиса и фатальных ошибок, конечно)?
Если в Bootstrap возникает исключение, оно не может быть передано в ErrorController
потому что ваше приложение еще не настроено, так что он еще не знает об ErrorController
.
Вам придется использовать что-то еще, чтобы справиться с этим.
У приложения, которое, скорее всего, будет бросать неискушенное исключение в Bootstrap, безусловно, не очень хорошо. Вы должны поймать Исключения, которые происходят в Bootstrap, и обрабатывать их соответственно.
Но если вы подключаетесь к базе данных JIT (Just In Time), проблем не должно быть. Фактически вы можете переместить соединение с базой данных после загрузки, используя плагины Front Controller. Настройка соединения с DB может быть в _dispatchLoopStartup()
если вам не нужно настраивать другие вещи (например, маршруты, некоторые переводы перед отправкой и т. Д.).
//in bootstrap $front->registerPlugin(new Awesome_Db_Plugin($zendConfigWithDbOptions)); // in plugin (options injected via constructor to private member public function dispatchLoopStartup() { $db = Zend_Db::factory($this->_options); Zend_Registry::set('db', $db); }
Таким образом, каждое исключение, возникшее во время соединения db, будет запущено после $front->dispatch();
это из моего index.php, может быть, это будет полезно:
//bootstrap, and run application try { require_once 'Zend/Application.php'; //create application and configure it. $application = new Zend_Application( getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'production', array('config' => array(APPLICATION_PATH . DS . 'configs' . DS . 'application.ini')) ); //run application $application->bootstrap()->run(); } catch (Exception $e) { //fallback for uncatched exceptions ob_clean(); //ensure error will be logged and firephp backend, if enabled, will send log messages if(is_object($application) && $application->bootstrap('log') && Zend_Registry::isRegistered('Zend_Log') ) { Zend_Registry::get('Zend_Log') ->log($e,Zend_Log::CRIT); } $wildfire = Zend_Wildfire_Channel_HttpHeaders::getInstance(); if(!($response = Zend_Controller_Front::getInstance()->getResponse())) { $response = new Zend_Controller_Response_Http(); $wildfire->setRequest(new Zend_Controller_Request_Http()); $wildfire->setResponse($response); } if($response->canSendHeaders()) { $response->clearHeaders(); $response->setHttpResponseCode(500); $wildfire->flush(); $response->sendResponse(); } //put static html for error page here echo 'Startup error occured. Try again later'; }
note : Zend_Registry::isRegistered('Zend_Log')
Экземпляр Zend_Log, зарегистрированный в реестре в моем расширенном ресурсе приложения