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

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;
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值