您好,登錄后才能下訂單哦!
異常機制
一.異常基本知識
1.定義:異常處理用于在指定的錯誤(異常)情況發生時改變腳本的正常流程,這過程稱為異常.
2.基本用法:
try
{
//可能出現的錯誤(異常)代碼
}
catch(Exception $e)
{
//自己處理:捕捉異常并處理,
//自己不處理:拋出一個異常,即如下:
throw $e;
}
其中,Exception是異常類(php中定義好的一個類,具體參見php參考文檔:語音參考->異常處理).它已經封裝好很多方法,常用如下:
function __construct($message = null, $code = 0);
final function getMessage(); // 返回異常信息
final function getCode(); // 返回異常代碼
final function getFile(); // 返回發生異常的文件名
final function getLine(); // 返回發生異常的代碼行號
final function getTrace(); // backtrace() 數組
final function getTraceAsString(); // 已格成化成字符串的 getTrace() 信息
/* 可重載的方法 */
function __toString(); // 可輸出的字符串
3.入門案例
案例1:
<?php try{ adduser("weimin"); echo "adduser()如果出現異常,這句話就不會出現<br>"; updateuser("wly1"); echo "updateuser()如果出現異常,這句話就不會出現<br>"; } catch(Exception $e) { echo "error!".$e->getMessage(); //getMessage()為異常中一個函數,可返回異常信息 } function adduser($username) { if($username=="weimin") { } else { throw new Exception("添加失敗");//拋出異常,及返回一個異常 } } function updateuser($username) { if($username=="wly") { } else { throw new Exception("修改失敗");//拋出異常 } } ?>
結果:
adduser()如果出現異常,這句話就不會出現
error!修改失敗
來自 <http://localhost/exception/exception01.php>
二.異常使用的注意事項
1.異常的基本處理:
(1).當異常被拋出,其后的代碼不會繼續執行,php嘗試查找匹配的catch代碼塊;見案例1.
(2).如果異常沒有被捕獲,而且有沒有使用set_exception_handler()做相應的處理,那么會發生一個嚴重的錯誤(致命錯誤),并輸出"Uncaught Exception"(未捕獲異常)的錯誤消息;
(3).當catch一個異常,可以進行處理或者不進行處理(在catch函數中,直接拋出異常,即 throw $e,這時將啟動php系統默認異常處理器(函數)來處理,見案例2。或者自己定義一個頂級異常處理器(函數),見案例3);
通俗理解:即第一次拋出異常后,使用try{},ctach{}捕獲到第一次拋出的異常,這時我們如果不對第一次拋出的異常進行處理,可以將此異常進行第二次拋出,這時,此異常將交給php默認異常處理器(函數)進行處理,或者交給用戶自己定義的頂級異常處理器(函數)進行處理。
其中,定義頂級異常處理,需要兩個步驟:
步驟一:定義頂級異常處理函數;
步驟二:修改默認定義異常處理函數set_exception_handler("函數名");
案例2:
<?php function A1($val) { if($val=="A") { throw new Exception ("不要輸入A");//第一次拋出異常 } } function B1($val) { if($val=="B") { throw new Exception ("不要輸入B");//第一次拋出異常 } } try { A1("A"); } catch(Exception $e) { throw $e; //第二次拋出異常 /*捕獲異常后,繼續拋出異常(第二次拋出異常),這時候將會啟動php默認的異常處理器來處理, 也可以自己定義一個頂級異常處理*/ } ?>
結果:
Fatal error: Uncaught exception 'Exception' with message '不要輸入A' in E:\Software_default\wamp_wwwroot\exception\exception02.php:6 Stack trace: #0 E:\Software_default\wamp_wwwroot\exception\exception02.php(18): A1('A') #1 {main} thrown in E:\Software_default\wamp_wwwroot\exception\exception02.phpon line 6
來自 <http://localhost/exception/exception02.php>
案例3:
<?php function MyException($e)//用戶定義的頂級異常處理函數 { echo "<b>我是頂級異常處理函數,</b>其中,異常信息為:".$e->getMessage(); } set_exception_handler("MyException");//修改默認的頂級異常處理函數 function A1($val) { if($val=="A") throw new Exception ("不要輸入A");//拋出異常 } function B1($val) { if($val=="B") throw new Exception ("不要輸入B"); } try { A1("A"); } catch(Exception $e) { throw $e; /*繼續拋出異常,這時候將會啟動php默認的異常處理器來處理, 也可以自己定義一個頂級異常處理*/ } ?>
結果:
我是頂級異常處理函數,其中,異常信息為:不要輸入A
來自 <http://localhost/exception/exception03.php>
(4).如果拋出一個異常,就必須捕獲它(否則會報錯,產生Fatal error錯誤),或者使用用戶定義的頂級異常處理函數進行處理
2.也可以自己定義一個異常類
class MyException Exception
{
}
3.使用多個catch代碼塊可以捕獲不同種類的異常
(1).基本用法
try
{
//代碼
//可能拋出多種異常
}
catch(PDOException $e)//數據庫異常
{
//代碼
}
catch(Exception $e)
{
//代碼
}
(2).案例
案例4:
<?php //定義一個異常類 class MyException1 extends Exception{ } class MyException2 extends Exception{ } function A() { throw new MyException1("a"); } function B() { throw new MyException1("b"); } function C() { try{ A();//拋出MyException1 B();//拋出MyException2 } catch(Exception1 $e1){ echo $e1->getMessage(); } catch(Exception2 $e2){ echo $e2>getMessage(); } } C(); ?>
結果:
Fatal error: Uncaught exception 'MyException1' with message 'a' in E:\Software_default\wamp_wwwroot\exception\exception04.php:12 Stack trace: #0 E:\Software_default\wamp_wwwroot\exception\exception04.php(21): A() #1 E:\Software_default\wamp_wwwroot\exception\exception04.php(31): C() #2 {main} thrown in E:\Software_default\wamp_wwwroot\exception\exception04.phpon line 12
來自 <http://localhost/exception/exception04.php>
由于產生不捕獲的異常,php默認顯示其異常處理函數,這時,我們添加用戶自定義的頂級處理函數
案例5:
<?php //定義一個異常類 class MyException1 extends Exception{ } class MyException2 extends Exception{ } function MyException($e) { echo "<b>我是頂級異常處理函數,</b>其中,異常信息為:".$e->getMessage(); } set_exception_handler("MyException");//修改默認的頂級異常處理函數 function A() { throw new MyException1("a"); } function B() { throw new MyException1("b"); } function C() { try{ A();//拋出MyException1 B();//拋出MyException2 } catch(Exception1 $e1){//Exception1 是異常類名 echo $e1->getMessage(); } catch(Exception2 $e2){//Exception2是異常類名 echo $e2>getMessage(); } } C(); ?>
結果:
我是頂級異常處理函數,其中,異常信息為:a
來自 <http://localhost/exception/exception05.php>
3.PHP異常拋出的BUG
案例6:
<?php try{ $a=8/0; } catch(Exception $e){ echo $e->getMessage(); echo "異常"; } ?>
結果:
Warning: Division by zero in E:\Software_default\wamp_wwwroot\exception\exception06.phpon line 3
來自 <http://localhost/exception/exception06.php>
在案例6中,8/0,php認為是錯誤,而不是異常,所以,沒有拋出異常,因此捕獲不到異常
案例7:
<?php try{ $f=fopen("aa.txt","r");//aa.txt在當前路徑下并不存在 } catch(Exception $e){ echo $e->getMessage(); echo "異常"; } ?>
結果:
Warning: fopen(aa.txt) [function.fopen]: failed to open stream: No such file or directory in E:\Software_default\wamp_wwwroot\exception\exception07.phpon line 3
來自 <http://localhost/exception/exception07.php>
在案例7中, fopen()是一個很老的函數,從php1就已經存在了,當時并沒有異常處理機制,php認為是錯誤,而不是異常,所以,沒有拋出異常,因此捕獲不到異常
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。