挂钩错误处理周期

时间:2011-03-19 23:50:44

标签: php zend-framework zend-controller zend-log

我正在构建一个监控解决方案,用于记录PHP错误,未捕获的异常以及用户想要记录到数据库表的任何其他内容。替代商业Zend Server中的监控解决方案。

我编写了一个Monitor类,它扩展了Zend_Log并可以处理所有提到的情况。 我的目标是将配置减少到一个地方,即Bootstrap。目前我正在初始化显示器,如下所示:

protected function _initMonitor()
{
    $config = Zend_Registry::get('config');
    $monitorDb = Zend_Db::factory($config->resources->db->adapter, $config->resources->db->params);

    $monitor = new Survey_Monitor(new Zend_Log_Writer_Db($monitorDb, 'logEntries'), $config->projectName);

    $monitor->registerErrorHandler()->logExceptions();
}

registerErrorHandler()方法允许php错误记录到数据库,logExceptions()方法是一个扩展,只是设置一个受保护的标志。

在ErrorController errorAction中,我添加以下行:

//use the monitor to log exceptions, if enabled
$monitor = Zend_Registry::get('monitor');

if (TRUE == $monitor->loggingExceptions)
{
    $monitor->log($errors->exception);
}

我想避免在ErrorController中添加代码,我宁愿动态注册一个插件。这将使用户更容易集成到现有项目中。

问题:我可以注册使用postDispatch挂钩的控制器插件并实现相同的效果吗?我不明白哪些事件会触发errorAction,如果在电路的多个阶段有多个事件,我是否需要使用几个钩子?

2 个答案:

答案 0 :(得分:1)

使用堆栈索引101注册您的插件。检查routeShutdown和postDispatch上的响应对象中的异常。

$response = $this->getResponse();
if ($response->isException()) {
   $exceptions = $response->getException();
}

检查是否在错误处理程序循环中抛出了异常,你必须将dispatch()放在try-catch块中

答案 1 :(得分:0)

Xerkus接受的答案让我走上正轨。不过,我想补充一些关于我的解决方案的信息。

我写了一个看起来像这样的Controller插件:

class Survey_Controller_Plugin_MonitorExceptions extends Zend_Controller_Plugin_Abstract
{    
    public function postDispatch(Zend_Controller_Request_Abstract $request)
    {
        $response = $this->getResponse();
        $monitor = Zend_Registry::get('monitor');

        if ($response->isException())
        {
            $monitor->log($response);
        }
    }
}

请注意,如果使用$ response-> getException(),则会获得一个Zend_Exception实例数组。在我理解了之后,我只是在我的logger方法中添加了一个foreach循环,它将每个Exception分别写入日志。

现在几乎所有东西都按预期工作。目前我仍然记录了两个相同的异常,这不是我所期望的。我将不得不通过SO上的另一个问题来研究。