PHP基礎:異常處理Exception

hizengzeng發表於2019-02-16

Exception是所有異常的基類。

Exception {
    /* 屬性 */
    protected string $message ;
    protected int $code ;
    protected string $file ;
    protected int $line ;
    
    /* 方法 */
    public __construct ([ string $message = "" [, int $code = 0 [, Exception $previous = NULL ]]] )
    final public string getMessage ( void )
    final public Exception getPrevious ( void )
    final public int getCode ( void )
    final public string getFile ( void )
    final public int getLine ( void )
    final public array getTrace ( void )
    final public string getTraceAsString ( void )
    public string __toString ( void )
    final private void __clone ( void )
}
Exception::__construct — 異常建構函式
Exception::getMessage — 獲取異常訊息內容
Exception::getPrevious — 返回異常鏈中的前一個異常
Exception::getCode — 獲取異常程式碼
Exception::getFile — 獲取發生異常的程式檔名稱
Exception::getLine — 獲取發生異常的程式碼在檔案中的行號
Exception::getTrace — 獲取異常追蹤資訊
Exception::getTraceAsString — 獲取字串型別的異常追蹤資訊
Exception::__toString — 將異常物件轉換為字串
Exception::__clone — 異常克隆

以上部分來自官網:http://php.net/manual/zh/clas…

下面是參考《PHP5權威程式設計》
try,catch,throw
異常處理使用3中語言結構:try,catch,throw。為了處理一個異常,需要在try程式碼塊中執行一些程式碼

try{
    $article->display();
}

try程式碼只是PHP留意在程式碼塊裡的程式碼執行時產生的異常。如果出現了異常,它馬上被傳遞給緊跟著try程式碼塊的一個或者更多的獲取程式碼塊中:

catch(Exception $e){
    die($e->getMessage());
}

變數$e似乎包含了一個物件。它包含的異常的確是物件,唯一條件就是必須從Exception類繼承。
如果想在你自己的程式碼中產生一個異常,使用throw語句:

$fp = @fopen($fileName,`r`);
if(!is_resource($fp)){
    throw new FileException(`could not open`);
}

可以看出異常是個物件,throw只是簡單的使用這個特定的物件作為異常的一部分
可以定義異常:

class IOException extends Exception{}
class FileException extends Exception{}

異常類中不需要成員變數或者方法:你需要的所有內容都已經在內建Exception類中定義了。

PHP在catch語句中使用所謂的“是一”關係對類的名字和異常物件做檢查。也就是,如果該異常物件是一個catch類的例項,或者其子類的例項,PHP就執行catch程式碼
如:

try{
    $article->display();
}catch(IOException $e){
    print `IOException`;
}catch(FileException $e){
    print `FileException`;
}

這個例子中IOException的catch同時捕獲到IOException和FileException,因為FileException是從IOException繼承的

如果每一個catch都沒能捕獲到異常,那麼會將該異常傳遞給呼叫的函式,給呼叫的函式提供機會來捕獲。
如果異常在任何地方都沒能捕獲,那麼PHP會提供最後的機會:異常處理函式。預設情況下PHP列印出錯誤資訊、類的名字和一個堆疊資訊。
通過呼叫set_exception_handler(),可以註冊異常處理函式

function my_exception(Exception $e){
    print `error is `.$e->getMessage();
    exit;
}

set_exception_handler(`my_exception`);

這個函式用來處理所有沒能在catch中獲取的異常,異常處理函式中不能再丟擲異常。

看看ThinkPHP中的做法:

set_exception_handler(array(`Think`,`appException`));

static public function appException($e) {
    halt($e->__toString());
}

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

在框架的入口註冊異常處理函式:先引入對應的模板檔案,然後在模板檔案中直接顯示出錯誤資訊

相關文章