ThinkPHPソース分析---異常処理

4556 ワード

ThinkPHPの異常処理
TPフレームワークのベースクラスロードは、ThinkThinkというクラスに多く置かれており、異常処理も例外ではない.図に示すように、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;
      }
    }