PHP筆記 | 異常處理
1. 丟擲一個異常
-
從PHP5開始,PHP支援
異常處理
,異常處理
是面向物件一個重要特性
,PHP程式碼中的異常通過
throw
丟擲,異常丟擲之後,後面的程式碼將不會再被執行。
-
既然丟擲異常會中斷程式執行,那麼為什麼還需要使用異常處理?
異常丟擲
被用於在遇到未知錯誤
,或者
不符合預先設定的條件
時,通知客戶程式,以便進行其他相關處理,不至於使程式直接報錯中斷。
-
當代碼中使用了
try catch
的時候,丟擲的異常
會在catch
中捕獲,否則
會直接中斷
。
- 基本語法
try{ //可能出現錯誤或異常的程式碼 //catch表示捕獲,Exception是php已定義好的異常類 } catch(Exception $e){ //對異常處理,方法: //1、自己處理 //2、不處理,將其再次丟擲 }
-
處理程式包括:
Try
-使用異常的函式
應該位於 "try"程式碼塊內。如果沒有
觸發異常
,則程式碼將照常
繼續執行。但是如果
異常被觸發
,會丟擲
一個異常。Throw
- 這裡規定
如何觸發異常
。注意:每一個
當然可以對應"throw"
必須對應至少一個 "catch"
,多個"catch"
Catch
-"catch"
程式碼塊會捕獲異常
,並建立
一個包含異常資訊的物件
。
//建立可丟擲一個異常的函式 function checkNum($number){ if($number>1){ throw new Exception("異常提示-數字必須小於等於1"); } return true; } //在 "try" 程式碼塊中觸發異常 try{ checkNum(2); //如果異常被丟擲,那麼下面一行程式碼將不會被輸出 echo '如果能看到這個提示,說明你的數字小於等於1'; }catch(Exception $e){ //捕獲異常 echo '捕獲異常: ' .$e->getMessage(); }
demo分析:
-
建立
checkNum()
函式。
檢測數字(輸入引數)是否大於 1。
如果是,則丟擲一個異常。 -
在
"try"
程式碼塊中呼叫checkNum()
函式。 -
checkNum()
函式中的異常被丟擲 -
"catch"
程式碼塊接收
到該異常
,
並建立
一個包含異常資訊的物件 ($e)
。 -
通過從這個
exception 物件
呼叫$e->getMessage()
,
輸出
來自該異常的錯誤訊息
<?php $filename = 'test.txt'; try { if (!file_exists($filename)) { throw new Exception('檔案不存在'); } } catch(Exception $e) { echo $e->getMessage(); } echo '<br>'.'----------------------------------'.'<br>'; function checkNum($number){ if($number>1){ throw new Exception("異常提示-數字必須小於等於1"); } return true; } //在 "try" 程式碼塊中觸發異常 try{ checkNum(2); //如果異常被丟擲,那麼下面一行程式碼將不會被輸出 echo '如果能看到這個提示,說明你的數字小於等於1'; }catch(Exception $e){ //捕獲異常 echo '捕獲異常: ' .$e->getMessage(); }
demo:
檔案不存在 ---------------------------------- 捕獲異常: 異常提示-數字必須小於等於1
2. 異常處理類
-
PHP具有很多
異常處理類
,其中
Exception
是所有異常處理
的基類
。 -
Exception
具有幾個基本屬性與方法
,.屬性:
message
異常訊息內容code
異常程式碼file
丟擲異常的檔名line
丟擲異常在該檔案的行數方法:
getTrace
獲取異常追蹤資訊getTraceAsString
獲取異常追蹤資訊的字串getMessage
獲取出錯資訊
如果必要的話,可以通過繼承Exception類來建立自定義的異常處理類。
//自定義的異常類,繼承了PHP的異常基類Exception class MyException extends Exception { function getInfo() { return '自定義錯誤資訊'; } } try { //使用異常的函式應該位於 "try"程式碼塊內。如果沒有觸發異常,則程式碼將照常繼續執行。但是如果異常被觸發,會丟擲一個異常。 throw new MyException('error');//這裡規定如何觸發異常。注意:每一個 "throw" 必須對應至少一個 "catch",當然可以對應多個"catch" } catch(Exception $e) {//"catch" 程式碼塊會捕獲異常,並建立一個包含異常資訊的物件 echo $e->getInfo();//獲取自定義的異常資訊 echo $e->getMessage();//獲取繼承自基類的getMessage資訊 }
綜合demo:
<?php class MyException extends Exception { function getInfo() { return '自定義錯誤資訊'; } } try { throw new MyException('error'); } catch(Exception $e) { echo $e->getInfo().'<br>'; echo $e->getMessage().'<br>'; echo $e->getTrace().'<br>'; echo $e->getTraceAsString(); }
執行結果:
自定義錯誤資訊 error Array #0 {main}
3. 捕獲異常資訊
-
可以通過
try catch
來捕獲異常,將
執行
的程式碼放在try程式碼塊中,一旦其中的程式碼丟擲異常,就能在
catch
中捕獲
。 -
在實際應用中,不會輕易的丟擲異常,
只有在極端情況或者非常重要的情況下,才會丟擲異常,
丟擲異常,可以保障程式的正確性與安全,避免導致不可預知的bug。
try { //... } catch(Exception $ex) { //... } echo '異常處理後,繼續執行其他程式碼';
-
注意,對照第一節筆記,try程式碼塊中,丟擲異常程式碼的下一行是不會再執行的;
但
try catch
後面的程式碼是可以正常執行,不受影響;(除非catch中程式碼也錯誤)
4. 獲取錯誤發生的所在行
-
實際應用中,通常會獲取足夠多的異常資訊,寫入到錯誤日誌中。
通過將報錯的檔名、行號、錯誤資訊、異常追蹤資訊等記錄到日誌中,以便除錯與修復問題。
demo:
<?php try { throw new Exception('wrong'); } catch(Exception $ex) { $msg = 'Error:'.$ex->getMessage()."\n"; $msg.= $ex->getTraceAsString()."\n"; $msg.= '異常行號:'.$ex->getLine()."\n"; $msg.= '所在檔案:'.$ex->getFile()."\n"; //將異常資訊記錄到日誌中 file_put_contents('error.log', $msg); echo $msg; }
執行結果:
Error:wrong #0 {main} 異常行號:3 所在檔案:index.php