1. 程式人生 > >【PHP】解析PHP中的錯誤和異常處理

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

not tty 不支持 版本 adding all 操作 lin ttr

目錄結構:

contents structure [-]
  1. 錯誤級別
  2. 自定義處理器
  3. 設置異常日誌
  4. 自定義異常類

在這篇文章中,筆者將會闡述PHP中的異常處理,希望能夠對你有所幫助。

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。


在知道了這些錯誤級別後,我們開始調整錯誤報告級別,既可以通過修改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屬性的話,可以通過:

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);
例如:

<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";
    ?>

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