Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/296.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php Zend Framework 2-捕获和记录异常的最佳方法,包括在工厂内_Php_Error Handling_Zend Framework2 - Fatal编程技术网

Php 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

下面的Zend Framework 2代码创建了一个弹性搜索客户端。但是,如果由于服务不可用而无法连接到弹性搜索,则会引发异常

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进程堆栈。我只是觉得在工厂过程中处理工厂错误是很顺利的。最终,使用结果实例时的错误和异常将在控制器中处理(如请求失败等)。