【PHP】解析PHP中的錯誤和異常處理

目錄結構:php

contents structure [-]

在這篇文章中,筆者將會闡述PHP中的異常處理,但願可以對你有所幫助。html

1.錯誤級別

PHP5中定義了16種不一樣的錯誤級別,下面僅僅粘貼其中幾種。程序員

級別常量 錯誤值 錯誤報告描述
E_ERROR 1 致命的運行時錯誤(阻止腳本執行)
E_WARNING 2 運行時警告(非致命性錯誤)
E_PARSE 4 從語法中解析錯誤
E_NOTICE 8 運行時注意消息(多是或可能不是一個問題)
E_CORE_ERROR 16 PHP啓動時初始化過程當中的致命錯誤
E_CORE_WARNING 32 PHP啓動時初始化過程當中的警告(非致命性錯)
E_COMPILE_ERROR 64 編譯時致命性錯
E_COMPILE_WARNING 128 編譯時警告(非致命性錯)
E_USER_ERROR 256 用戶自定義的致命錯誤
E_USER_WARNING 512 用戶自定義的警告(非致命性錯誤)
E_USER_NOTICE 1024 用戶自定義的提醒
E_STRICT 2048 編碼標準化警告(建議如何修改以向前兼容)
E_ALL 32767

全部的錯誤、警告和注意信息,在PHP5.4.0以前的版本以前不包含E_STRICT錯誤級別。函數

注意:在PHP 5.4.x 中是32767,在PHP 5.3.x中是30719,在 PHP 5.2.x中是6143,在5.2.x以前的版本是2047。this


在知道了這些錯誤級別後,咱們開始調整錯誤報告級別,既能夠經過修改PHP配置文件,也能夠經過修改PHP腳本代碼來實現。編碼

先介紹如何經過修改PHP配置文件來實現,在PHP的配置文件(php.ini)中,display_errors直接控制PHP是否輸出錯誤、提醒和警告信息。它的值有On、Off、stdout、stderr:
On 或 stdout:表示輸出全部消息到標準的輸出流。
stderr:表示輸出全部消息到標準的錯誤流。
Off:表示不顯示任何消息。

還能夠經過PHP腳本代碼來修改php.ini配置文件,經過ini_set(...)函數能夠實現這個功能,
好比修改php.ini配置文件中的display_errors屬性的話,能夠經過:spa

ini_set("display_errors","On");

這裏是將全部的消息都輸出到標準輸出流。

例如:操作系統

<html>
    <head>
        <title>display_errors</title>
    </head>
    <body>
    <?php
        //ini_set("display_errors","Off");  
        echo "-------------------------------------<br/>";        
        gettype();//拋出警告信息
        echo "-------------------------------------<br/>";
    ?>
    </body>
</html>

效果圖:


給ini_set("display_errors","Off");取消註釋後,會看到以下效果:


經過手動修改PHP配置文件和ini_set函數,均可以達到這個功能,然而手動修改PHP配置文件的項目可移植性不強,推薦經過ini_set函數來實現。

display_errors至關於總開關,要麼開啓全部錯誤消息輸出,要麼關閉全部的錯誤消息輸出。那麼有沒有可以控制報告不一樣級別的錯誤設置呢?PHP提供的error_reporting()函數就能夠動態完成設置錯誤報告級別。如:error_reporting(E_ALL);
例如:rest

<html>
    <head>
        <title>display_errors</title>
    </head>
    <body>
    <?php
        error_reporting(E_ALL);//報告全部錯誤
        echo "-------------------------------------<br/>";
        gettype();
        echo "-------------------------------------<br/>";
    ?>
    </body>
</html>

效果與ini_set("display_errors","On");同樣。

error_reporting()能夠設置16中錯誤級別中的任何一種,強烈建議在設置的時候經過常量名來設置,在將來的版本中才能保證移植性。
error_reporting()也能夠接受位標誌,例如:日誌

error_reporting(E_ERROR | E_WARNING);

2.自定義處理器

經過上面的案例咱們能夠看到,全部拋出的錯誤都是在錯誤代碼處拋出的,這是標準的PHP錯誤處理函數。

 

然而PHP容許程序員自定義錯誤和異常處理器,可以徹底繞過PHP標準的錯誤和異常處理函數,這樣的話,就能夠自定義錯誤和異常的處理方式。

mixed set_error_handler ( callable $error_handler [, int $error_types = E_ALL | E_STRICT ] )

自定義的錯誤處理器,當有錯誤發生時,會調用該處理器設置的異常。

 

callable set_exception_handler ( callable $exception_handler )

自定義的異常處理器,當有未捕獲的異常拋出時候,該函數設置的處理器就會處理該異常。

 

restore_exception_handler()

當使用set_exception_handler設置過自定義異常處理器後,restore_exception_handler能夠恢復到以前的那個異常處理器。

 

restore_error_handler()

當使用set_error_handler設置過自定義錯誤處理器後,restore_error_handler能夠恢復到以前的那個錯誤處理器。

3.設置異常日誌

若是要設置異常日誌的話,那麼就要修改PHP配置文件php.ini。
error_reporting = E_ALL//將向PHP發送每一個錯誤
display_errors=Off     //不顯示錯誤報告
log_errors=On          //開啓日誌記錄
log_errors_max_log=1024// 每一個日誌項的最大長度
error_log="c:/myerror.log" //指定錯誤寫進的文件

在php文件中使用error_log()來記錄日誌,就能夠將信息寫入到myerror.log文件中。
好比:

error_log("unexpected error");

error_log不只能夠指定日誌的記錄文件,還能夠將日誌輸出到操做系統中,只要將error_log指定爲syslog就能夠了(Win 95不支持)。

4.自定義異常類

一個自定義的異常類必須從Exception派生,Exception類的元數據以下:

 Exception implements Throwable {
/* Properties */
protected string $message ;
protected int $code ;
protected string $file ;
protected int $line ;
/* Methods */
public __construct ([ string $message = "" [, int $code = 0 [, Throwable $previous = NULL ]]] )
final public string getMessage ( void )
final public Throwable getPrevious ( void )
final public mixed 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 )
}

其中__construct表示構造方法,能夠按照須要重寫它的構造方法和__toString()方法。
例如:

<?php
    /* 自定義的一個異常處理類,但必須是擴展內異常處理類的子類 */
    class MyCustomException extends Exception{
        //重定義構造器使第一個參數 message 變爲必須被指定的屬性
        public function __construct($message, $code=0){
            //能夠在這裏定義一些本身的代碼
         //建議同時調用 parent::construct()來檢查全部的變量是否已被賦值
            parent::__construct($message, $code);
        }
        public function __toString() {        
          //重寫父類方法,自定義字符串輸出的樣式
          return __CLASS__.":[".$this->code."]:".$this->message."<br>";
        }
        public function customFunction() {    
             //爲這個異常自定義一個處理方法
             echo "按自定義的方法處理出現的這個類型的異常<br>";
        }
    }

    try{
        throw new MyCustomException("Unexpected Exception");
    }catch(MyCustomException $e){
        echo $e;

        $e->customFunction();
    }
    echo "<br/>";
    echo "end";
    ?>
相關文章
相關標籤/搜索