【问题标题】:Implement Error Handling to my framework对我的框架实施错误处理
【发布时间】:2011-04-17 03:10:55
【问题描述】:

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

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

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

我的想法是创建一个名为 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 的错误系统,等等,因为有时我对如何构建它以防万一感到困惑。

【问题讨论】:

    标签: php error-reporting


    【解决方案1】:

    我不太确定你在做什么,但最直接的方法是使用嵌套的 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

    【讨论】:

    • 竖起大拇指,这是最可靠的方法。
    • 但这仅适用于了解异常的人,很多用户不了解,所以我也在跟踪可能未捕获的错误,甚至是由trigger_error触发的错误
    • 我更新了我的代码,看看您是否可以更好地了解我想要完成的工作,感谢您迄今为止的回复。
    【解决方案2】:

    你所拥有的看起来很可靠。您必须添加一些逻辑,以便在引发关闭脚本的错误时刷新 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),我会假设它会显示?

    【讨论】:

    • ob_clean 只是为了保护错误,例如空白空间和从库中显示的文本,直到应用程序启动。
    • 是的,只是一个小小的疏忽,想想还是算了:pastebin.com/2kWyDcNJ 然后执行 start();在加载所有核心之前,添加停止();在应用程序启动之前。到目前为止效果很好:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-11
    • 1970-01-01
    • 2012-05-27
    • 1970-01-01
    • 2011-06-11
    • 1970-01-01
    • 2013-04-20
    相关资源
    最近更新 更多