ThinkPHP源码分析----异常处理

来源:互联网 发布:掌盟书城java下载 编辑:程序博客网 时间:2024/04/29 19:45

ThinkPHP的异常处理

TP框架的基础类加载多放在\Think\Think这个类里,异常处理也不例外.

如图,TP在start方法中定义自定义错误和异常处理函数,以及脚本关闭函数.下面来看看各自的源码,在此之前先看一个错误输出函数,这个函数将会在各个处理函数中被调用:

static public function halt($error) {.    $e = array();    if (APP_DEBUG || IS_CLI) {        //调试模式下输出错误信息        if (!is_array($error)) {            // 获取当前脚本的回调跟踪            $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)) {            redirect($error_page);        } else {            $message        = is_array($error) ? $error['message'] : $error;            $e['message']   = C('SHOW_ERROR_MSG')? $message : C('ERROR_MESSAGE');        }    }    // 包含异常页面模板    $exceptionFile =  C('TMPL_EXCEPTION_FILE',null,THINK_PATH.'Tpl/think_exception.tpl');    include $exceptionFile;    exit;}
  • 调试模式下获取错误$error中的信息,记录下错误的信息,行数,文件,以及回调跟踪.然后在错误模板中打印输出.
  • 命令行模式下,关闭脚本,并将错误信息以gbk格式输出.
  • 生产模式下,直接进入错误模板.

捕获致命错误:

    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;            }        }    }

TP将发生错误这一时间记录进日志文件,之后清空并关闭缓存区,使用自定义函数halt将错误输出.

自定义异常处理函数:

static public function appException($e) {    $error = array();    $error['message']   =   $e->getMessage();    $trace              =   $e->getTrace();    if('E'==$trace[0]['function']) {        $error['file']  =   $trace[0]['file'];        $error['line']  =   $trace[0]['line'];    }else{        $error['file']  =   $e->getFile();        $error['line']  =   $e->getLine();    }    $error['trace']     =   $e->getTraceAsString();    Log::record($error['message'],Log::ERR);    // 发送404信息    header('HTTP/1.1 404 Not Found');    header('Status:404 Not Found');    self::halt($error);}

自定义错误处理函数:

static public function appError($errno, $errstr, $errfile, $errline) {  switch ($errno) {      case E_ERROR:      case E_PARSE:      case E_CORE_ERROR:      case E_COMPILE_ERROR:      case E_USER_ERROR:        ob_end_clean();        $errorStr = "$errstr ".$errfile." 第 $errline 行.";        if(C('LOG_RECORD')) Log::write("[$errno] ".$errorStr,Log::ERR);        self::halt($errorStr);        break;      default:        $errorStr = "[$errno] $errstr ".$errfile." 第 $errline 行.";        self::trace($errorStr,'','NOTIC');        break;  }}
0 0