为我的框架实现错误处理

时间:2010-09-25 09:27:31

标签: php error-reporting

我即将开始在我的框架中实现错误处理,并寻求有关如何构建它的一些建议。

首先让我解释一下我的框架目前是如何构建的:

我将框架启动与应用程序启动分开,因此应用程序启动过程中引起的任何错误都应该由专用于此的类专门处理。

我的想法是让一个名为Core_Error_exception的类会将错误报告设置为E_ALL,因为我的框架将严格控制 PHP 5.3 的错误,然后作为我的错误作为我的应用程序加载,我将在该类中运行一个关闭函数函数来恢复所有已更改的默认值。

我想要做的是捕获所有E_*_NOTICE而不是E_*_ERROR的错误,然后在应用程序启动之前我告诉班级停止捕获错误,因为Application_Error_Exception将会看到出于错误。

所以我需要一种方法来跟踪所有错误,包括异常和触发器,然后在应用程序初始化之前显示一个框架调试页面。

我正在寻找的那种课程是这样的:

class Core_Error_Exception
{
    var $previus_error_level,$captured_contents;

    private $stack_trace = array();

    public function Core_Error_Exception()
    {
        $this->previus_error_level = error_reporting(-1);
        set_error_handler(array($this,'_collect_error'));
        set_exception_handler(array($this,'_collect_error'));
        ob_start(array($this,'_capture'));
    }

    public function _collect_error($errno, $errstr, $errfile, $errline, $context)
    {
        $this->stack_trace[] = array(
            array('name' => 'Error ID:',    'value' => $errno),
            array('name' => 'Error String:','value' => $errstr),
            array('name' => 'Error File:',  'value' => $errfile),
            array('name' => 'Error Line:',  'value' => $errline),
            array('name' => 'Context PRE:', 'value' => $context)
        );
        var_dump($this->stack_trace);
    }

    /*
     * _capture is used to capture pre_bufferd content.
     */
    public function _capture($content,$bitfeild)
    {
        if($bitfeild & PHP_OUTPUT_HANDLER_START)
        {
            $this->captured_contents = $content;
        }

        if($bitfeild & PHP_OUTPUT_HANDLER_CONT)
        {
            $this->captured_contents .= $content;
        }

        if($bitfeild & PHP_OUTPUT_HANDLER_END)
        {
            $this->captured_contents .= $content;
        }
        return false;
    }
}

所以我要做的就是能够以防跌落的方式构造这个类,以便可以触发的任何通知错误都被放入一个数组中,如果调用了E_ERROR通知,那么这会自动运行此时关闭,以防止引起更多错误。

我将使用一个小的html模板处理程序,我可以将其传递给上下文错误集,因此如果适用,请注意错误和单个E_*_ERROR

与过去一样,构建此课程的最佳方式是我在进行错误跟踪/报告时遇到了一些困难。

已更新:使用当前班级

如果触发错误,例如trigger_error('test',XXX);我希望能够在应用程序启动或触发E_USER_ERROR之前跟踪所有错误。

有时候我很难完全掌握PHP的错误系统,等等,因为有时我会对如何构建错误系统感到困惑。

2 个答案:

答案 0 :(得分:3)

我不太确定你在做什么,但最直接的方法是使用嵌套的try块,

in Class Application:

    function run() {
        try {
            --do stuff
        } catch(AppException $e) {
            -- handle application-level exception
        }
        -- all other exceptions fall through


in Class Core:

    try {
        $core->init();
        $application->run(); <-- calls the above function
        $core->done();
    } catch(Exception $e) {
        --last chance exception handler
        --process exceptions the Application was unable to handle on its own
    }

为了能够以这种方式捕获php内置错误或trigger_error事件,您还应该始终安装errors-to-exceptions handler

答案 1 :(得分:0)

你看起来很稳固。您必须添加一些逻辑,以便在抛出关闭脚本的错误时刷新ob缓冲区中的输出并将所有收集的数据发送到错误HTML文件以显示跟踪。类似的东西:

public function _collect_error($errno, $errstr, $errfile, $errline, $context)
{
    $this->stack_trace[] = array(
        array('name' => 'Error ID:',    'value' => $errno),
        array('name' => 'Error String:','value' => $errstr),
        array('name' => 'Error File:',  'value' => $errfile),
        array('name' => 'Error Line:',  'value' => $errline),
        array('name' => 'Context PRE:', 'value' => $context)
    );

    if($errno == E_USER_ERROR) {
        ob_clean();
        // Pass collected data to HTML template
        // Display HTML
        exit();
    }

    var_dump($this->stack_trace);
}

我不是100%肯定你可以优雅地从致命错误中恢复,但是从你所说的你只是在寻找特定的非致命错误来关闭处理。

您对捕获缓冲内容的意图是什么?我会假设它显示如果您正在寻找的错误从未被击中或被抛出并显示错误屏幕(为什么我在错误函数中添加了ob_clean)?