什麼是php的異常處理?php的異常處理又會有哪些規則?

異常(Exception)是什麼

PHP 提供了一種錯誤處理方法。這種錯誤處理方法用於在異常情況發生時改變腳本的正常流程。也就是說異常處理是通過 try catch finally 語句和 throw 關鍵字捕捉異常使程式不會因此崩潰。

  1. Try - 使用異常的函數應該位於 try 代碼塊內。 如果沒有觸發異常,則代碼將照常繼續執行。 但是如果異常被觸發,會拋出一個異常。
  2. Throw - 拋出異常。 每一個 throw 必須對應至少一個 catch。
  3. Catch - 捕獲異常,並創建一個包含異常的訊息。
  4. Finally - 這個區塊可以放在catch之後或者直接取代catch。無論是否拋出異常,在 try catch 之後、跳出異常處理代碼執行其他後續代碼之前,放在finally內的代碼會先被執行。finally 跟 return 會互相影響。如果在 try 或 catch 寫 return 會先執行完 finally 內的代碼再 return。
異常的規則:
  • 需要進行異常處理的程式碼應該放入 try 程式碼塊內,以便捕獲潛在的異常。
  • 每個 try 或 throw 程式碼塊必須至少擁有一個對應的 catch 程式碼塊。
  • 使用多個 catch 程式碼塊可以捕獲不同種類的異常。
  • 可以在 try 程式碼塊內的 catch 程式碼塊中丟擲(再次丟擲)異常。
案例示範 :
<?php
function check($date)
{
    if($date>31 || $date<1)
    {
        throw new Exception("date不可以大於31或小於1");
    }
        return true;
}

try
{
    check(33);
}

catch(Exception $e)
{
    echo 'Error Message: ' .$e->getMessage();
}

finally {
    echo "\ntry finally.";
}
   
   ?>

一個 check function 檢查變數 date 是否大於31小於1,是的話拋出異常。然後在 try 區塊 call check function ,因為異常所以進到 catch 區塊印出錯誤訊息。

output :

Error Message: date不可以大於31或小於1
try finally.

自訂錯誤訊息

在 errorMessage function 內自定義我們想要的錯誤訊息,然後在 try 區塊內用 filter_var 過濾器檢查 email 格式是否正確,若不正確丟擲錯誤,再由 catch 區塊接住錯誤印出錯誤訊息。

<?php
class customException extends Exception
{
    public function errorMessage()
    {
        $errorMsg = '<b>'.$this->getMessage().'</b> Email輸入不正確';
        return $errorMsg;
    }
}
 
$email = "fsdsgsf gs//@gmail....do,";
 
try
{
    if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE)
    {
        throw new customException($email);
    }
}
 
catch (customException $e)
{
echo $e->errorMessage();
}
?>

output :

<b>fsdsgsf gs//@gmail....do,</b> Email輸入不正確

巢狀異常

當異常被丟擲時,我們可能希望以不同於標準的方式對它進行處理。可以在一個 catch 程式碼塊中再次丟擲異常。

<?php

class MyException extends Exception { }

class Test {
    public function testing() {
        try {
            try {
                throw new MyException('foo!');
            } catch (MyException $e) {
                // rethrow it
                throw $e;
            }
        } catch (Exception $e) {
            echo $e->getMessage();
        }
    }
}

$foo = new Test;
$foo->testing();

?>

output :

foo!

頂層異常處理器

我們可以利用set_exception_handler這個函式來設立一個function當我們在try丟出錯誤時不需要同時使用catch,會直接call function進行異常處理。示範如下:

<?php
function myException($exception)
{
	echo "<b>Exception:</b> " , $exception->getMessage();
}

set_exception_handler('myException');

throw new Exception('Uncaught Exception occurred');
?>

output :

Exception: Uncaught Exception occurred

常用方法函式:

  • getMessage():返回異常的訊息內容;
  • getCode():以數字形式返回異常程式碼;
  • getFile():返回發生異常的檔名;
  • getLine():返回發生錯誤的程式碼行號;
  • getTrace():返回 backtrace() 陣列;
  • getTraceAsString():返回已格式化成字串的、由函式 getTrace() 函式所產生的資訊;
  • __toString():產生異常的字串資訊,它可以過載。注意,該函式最前部是兩個下劃線。
getTrace()案例示範:

getTrace的意義是返回異常的關聯 ( backtrace ) array,array內有可能包含以下幾個

functionstring現在使用的函式名。
lineinteger使用到的函式在第幾行。
filestring目前的文件路徑。
classstring目前類的名稱。
objectobject現在的物件
argsarray如果在function中,列出function参数。如果在被引用的文件中,列出被引用的文件名。
<?php
function test() {
 throw new Exception;
}

try {
 test();
} catch(Exception $e) {
 var_dump($e->getTrace());
}
?>

output :

array(1) {
  [0]=>
  array(4) {
    ["file"]=>
    string(38) "/Users/sc/Desktop/php-practice/try.php"
    ["line"]=>
    int(7)
    ["function"]=>
    string(4) "test"
    ["args"]=>
    array(0) {
    }
  }