1、ThinkPHP源码学习-致命错误捕获及自定义错误输出

来源:互联网 发布:js点击按钮隐藏div 编辑:程序博客网 时间:2024/05/29 09:41

首先在 Think\Think::start() 静态方法中,使用 register_shutdown_function 函数注册致命错误处理方法。

register_shutdown_function('Think\Think::fatalError');

Think\Think::fatalError 方法中,首先记录错误日志,这个暂且不说。接着使用 error_get_last 函数获取错误信息,不过TP只匹配E_ERROR、E_PARSE、E_CORE_ERROR、E_COMPILE_ERROR、E_USER_ERROR 这五种错误类型,然后使用 ob_end_clean 函数清空并关闭输出缓冲区(这样做的目的是,不显示PHP自身的错误信息提示,而是采用自定义的错误提示),最后调用自定义错误提示方法。

// 致命错误捕获static public function fatalError() {    Log::save(); // 记录日志    if ($e = error_get_last()) {        switch($e['type']){            case E_ERROR:            case E_PARSE:            case E_CORE_ERROR:            case E_COMPILE_ERROR:            case E_USER_ERROR:                ob_end_clean();                self::halt($e);                break;        }    }}

self::halt($e) 方法细节:

// 错误输出static public function halt($error){    $e = array();    if (APP_DEBUG || IS_CLI) {        //调试模式下输出错误信息        if (!is_array($error)) {            // 如果错误信息格式不是数组,使用回溯跟踪函数debug_backtrace,可以定位到错误文件及错误行号。            $trace          = debug_backtrace();            $e['message']   = $error;            $e['file']      = $trace[0]['file'];            $e['line']      = $trace[0]['line'];            // 开启并打印输出缓冲区的内容            ob_start();            debug_print_backtrace();            $e['trace']     = ob_get_clean();        } else {            $e              = $error;        }        if(IS_CLI){            // 如果开启了命令行模式,直接输出错误信息。            exit(iconv('UTF-8','gbk',$e['message']).PHP_EOL.'FILE: '.$e['file'].'('.$e['line'].')'.PHP_EOL.$e['trace']);        }    } else {        //否则定向到错误页面        $error_page         = C('ERROR_PAGE');        if (!empty($error_page)) {            // 获取错误文件的URL路径,重定向至错误的文件,一般不会执行这段代码。            redirect($error_page);        } else {            // 在线上部署时,出于安全考虑,不应显示过多的敏感信息,            // 比如:错误文件及路径,错误行号,错误原因。            // C('SHOW_ERROR_MSG')为false时,显示tp预定义好的错误提示:C('ERROR_MESSAGE') 页面错误!请稍后再试~。            $message        = is_array($error) ? $error['message'] : $error;            $e['message']   = C('SHOW_ERROR_MSG')? $message : C('ERROR_MESSAGE');        }    }    // 最后一步就是加载错误模板,想用户展示错误信息    // 路径:项目根\ThinkPHP\Tpl\think_exception.tpl    // 至于模板是什么样子,自己可以随意写。        // 包含异常页面模板    $exceptionFile =  C('TMPL_EXCEPTION_FILE',null,THINK_PATH.'Tpl/think_exception.tpl');    include $exceptionFile;    exit;}

原创粉丝点击