異常(Exception)是什麼
PHP 提供了一種錯誤處理方法。這種錯誤處理方法用於在異常情況發生時改變腳本的正常流程。也就是說異常處理是通過 try catch finally
語句和 throw
關鍵字捕捉異常使程式不會因此崩潰。
- Try - 使用異常的函數應該位於 try 代碼塊內。 如果沒有觸發異常,則代碼將照常繼續執行。 但是如果異常被觸發,會拋出一個異常。
- Throw - 拋出異常。 每一個 throw 必須對應至少一個 catch。
- Catch - 捕獲異常,並創建一個包含異常的訊息。
- 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內有可能包含以下幾個
function | string | 現在使用的函式名。 |
line | integer | 使用到的函式在第幾行。 |
file | string | 目前的文件路徑。 |
class | string | 目前類的名稱。 |
object | object | 現在的物件 |
args | array | 如果在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) {
}
}