Php Zend Framework 2-捕获和记录异常的最佳方法,包括在工厂内
下面的Zend Framework 2代码创建了一个弹性搜索客户端。但是,如果由于服务不可用而无法连接到弹性搜索,则会引发异常Php Zend Framework 2-捕获和记录异常的最佳方法,包括在工厂内,php,error-handling,zend-framework2,Php,Error Handling,Zend Framework2,下面的Zend Framework 2代码创建了一个弹性搜索客户端。但是,如果由于服务不可用而无法连接到弹性搜索,则会引发异常 class ElasticClientFactory implements FactoryInterface { /** * Create service * * @param ServiceLocatorInterface $serviceLocator * @return \Elasticsearch\Client
class ElasticClientFactory implements FactoryInterface
{
/**
* Create service
*
* @param ServiceLocatorInterface $serviceLocator
* @return \Elasticsearch\Client
*/
public function createService(ServiceLocatorInterface $serviceLocator)
{
return new Client(
$serviceLocator->get('Config')['elastic']['cluster']
);
}
}
我的理解是,要在Zend中创建默认的错误处理程序,我应该使用以下代码
$sharedManager = $event->getApplication()->getEventManager()->getSharedManager();
$sm = $event->getApplication()->getServiceManager();
$sharedManager->attach('Zend\Mvc\Application', 'dispatch.error',
function($event) use ($sm) {
if ($event->getParam('exception')){
$sm->get('Logger')->crit($event->getParam('exception'));
}
});
但是,此代码仅捕获控制器中或调度过程中抛出的异常。是否有方法捕获使用工厂创建服务时引发的异常。这可能会发生很多情况,例如,如果数据库关闭或应用程序尝试连接到的任何服务。我似乎找不到正确的方法来捕获工厂中抛出的异常,并让它们由上面的全局错误处理程序处理
为了解决这个问题,现在我已经在记录器上注册了一个异常处理程序,它将记录工厂中抛出的异常,但这感觉不正确
Logger::registerExceptionHandler($logger);
最后,我创建了一个单独的Zend Framework 2模块,并在onBootstrap方法中执行了以下操作
public function onBootstrap(MvcEvent $event)
{
$eventManager = $event->getApplication()->getEventManager();
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach($eventManager);
$logger = $event->getApplication()->getServiceManager()->get('Logger');
捕获调度期间错误的异常
$sharedManager = $event->getApplication()->getEventManager()->getSharedManager();
$sm = $event->getApplication()->getServiceManager();
$sharedManager->attach('Zend\Mvc\Application', 'dispatch.error',
function($event) use ($sm) {
if ($event->getParam('exception')){
$sm->get('Logger')->crit($event->getParam('exception'));
}
});
捕获应用程序代码中未捕获的异常。例如,如果数据库服务器出现故障
set_exception_handler(function($exception) use ($sm, $event) {
//ensure that the application log, logs a 500 error
$event->getResponse()->setStatusCode(500);
$extractor->setResponse($event->getResponse());
http_response_code(500);
$sm->get('Logger')->crit($exception);
});
在响应上设置400或500错误消息时记录的全局catchall。这主要是为了记录日志
$eventManager->attach(MvcEvent::EVENT_FINISH,
function ($e) use ($logger) {
$statusCode = $e->getResponse()->getStatusCode();
$sm = $e->getApplication()->getServiceManager();
if($statusCode >= 500) {
$e->getResponse()->setStatusCode($statusCode);
$sm->get('Logger')->crit($e->getResponse());
}
if($statusCode >= 400 && $statusCode < 500) {
$e->getResponse()->setStatusCode($statusCode);
$sm->get('Logger')->err($e->getResponse());
}
}
);
$eventManager->attach(MvcEvent::EVENT\u FINISH,
函数($e)使用($logger){
$statusCode=$e->getResponse()->getStatusCode();
$sm=$e->getApplication()->getServiceManager();
如果($statusCode>=500){
$e->getResponse()->setStatusCode($statusCode);
$sm->get('Logger')->crit($e->getResponse());
}
如果($statusCode>=400&$statusCode<500){
$e->getResponse()->setStatusCode($statusCode);
$sm->get('Logger')->err($e->getResponse());
}
}
);
我认为最好的方法是在factory中尝试/捕获异常,这样您可以选择返回false或空客户机…此外,factory构建期间提供服务(您可以访问$serviceLocator),因此您可以注册一个记录器并使用它记录错误,而不会干扰MVC进程堆栈。我只是觉得在工厂过程中处理工厂错误是很顺利的。最终,使用结果实例时的错误和异常将在控制器中处理(如请求失败等)。