例外用於如果發生指定的錯誤改變腳本的正常流動。
什麼是異常
隨著PHP 5來處理錯誤的一個新的面向對象的方式。
異常處理用於如果指定的錯誤改變代碼執行的正常流動(exceptional)條件發生。 這種情況被稱為異常。
這是當異常被觸發,通常會發生什麼:
- 當前代碼狀態被保存
- 該代碼執行將切換到預定義的(custom)異常處理函數
- 根據不同的情況,處理程序就可以恢復的代碼保存狀態下執行,中止執行腳本或從其他位置繼續腳本代碼
我們會表現出不同的錯誤處理方法:
- 基本使用的例外
- 創建自定義異常處理程序
- 多個異常
- 重新拋出異常
- 設置頂層異常處理程序
Note:例外只應該錯誤的條件下使用,而不應使用在指定點跳轉到另一地點的代碼。
例外的基本使用
當一個異常被拋出,下面的代碼就不會被執行,而PHP將試圖找到匹配的"catch"塊。
如果一個異常沒有被捕獲,一個致命的錯誤將與發出"Uncaught Exception"消息。
讓我們試著拋出一個異常,不會夾住它:
<?php
//create function with an exception
function checkNum($number) {
if($number>1) {
throw new Exception("Value must be 1 or below");
}
return true;
}
//trigger exception
checkNum(2);
?>
上面的代碼會獲得類似這樣的錯誤:
Fatal error : Uncaught exception 'Exception'
with message 'Value must be 1 or below' in C:\webfolder\test.php:6
Stack trace: #0 C:\webfolder\test.php(12):
checkNum(28) #1 {main} thrown in C:\webfolder\test.php on line 6
嘗試,拋出和捕獲
為了避免從上面例子中的錯誤,我們需要創建適當的代碼來處理異常。
適當的異常代碼應包括:
- 使用異常應在一個功能-嘗試"try"塊。 如果異常不會觸發,代碼將繼續正常。 但是,如果觸發的例外,一個異常"thrown"
- 扔掉 - 這是你如何觸發一個例外。 每一個"throw"必須至少有一個"catch"
- 捉-甲"catch"塊檢索一個例外,並創建包含異常信息的對象
讓我們嘗試觸發有效代碼的異常:
<?php
//create function with an exception
function checkNum($number) {
if($number>1) {
throw new Exception("Value must be 1 or below");
}
return true;
}
//trigger exception in a "try" block
try {
checkNum(2);
//If the exception is thrown, this text will not be shown
echo 'If you see this, the number is 1 or below';
}
//catch exception
catch(Exception $e) {
echo 'Message: ' .$e->getMessage();
}
?>
上面的代碼會獲得類似這樣的錯誤:
Message: Value must be 1 or below
為例進行了說明:
上面的代碼拋出異常和捕獲它:
- 所述checkNum()創建功能。 它檢查,如果數大於1,如果是,則拋出異常
- 該checkNum()函數被調用一個"try"塊
- 該範圍內的異常checkNum()函數拋出
- 的"catch"塊檢索異常,並創建一個對象($e)包含異常信息
- 從異常的錯誤消息是由呼叫呼應$e-> getMessage()從所述異常對象
然而,一個辦法讓周圍的"every throw must have a catch"規則是設定一個最高水平異常處理程序來處理漏網之魚錯誤。
創建一個自定義異常類
要創建您必須創建一個特殊類時異常在PHP時,可以調用函數的自定義異常處理程序。 類必須是異常類的擴展。
自定義異常類從PHP的異常類繼承的屬性,你可以添加自定義的功能吧。
讓我們創建一個異常類:
<?php
class customException extends Exception {
public function errorMessage() {
//error message
$errorMsg = 'Error on line '.$this->getLine().' in '.$this->getFile()
.': <b>'.$this->getMessage().'</b> is not a valid E-Mail address';
return $errorMsg;
}
}
$email = "[email protected]";
try {
//check if
if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE) {
//throw exception if email is not valid
throw new customException($email);
}
}
catch (customException $e) {
//display custom message
echo $e->errorMessage();
}
?>
新的類是舊的例外類與另外的一個副本errorMessage()函數。 既然是老類的副本,並將其從舊的類繼承的屬性和方法,我們可以使用異常類的方法,如getLine()和getFile()和getMessage()
為例進行了說明:
上面的代碼拋出異常,並用一個定制的異常類捕獲它:
- 該customException()類為舊的例外類的擴展創建。 這樣,它繼承了舊的例外類的所有方法和屬性
- 所述errorMessage()創建功能。 如果電子郵件地址無效,該函數返回一個錯誤信息
- 在$電子郵件變量設置為一個字符串,這不是一個有效的電子郵件地址
- 在"try"塊被執行並拋出一個異常,因為電子郵件地址無效
- 的"catch"塊捕捉異常並顯示錯誤消息
多個異常
這是可能的腳本中使用多個異常檢查多個條件。
有可能使用幾種的if..else塊,一個開關,或嵌套多個異常。 這些例外可以使用不同的異常類返回不同的錯誤信息:
<?php
class customException extends Exception
{
public function errorMessage()
{
//error message
$errorMsg = 'Error on line '.$this->getLine().' in '.$this->getFile()
.': <b>'.$this->getMessage().'</b> is not a valid E-Mail address';
return $errorMsg;
}
}
$email = "[email protected]";
try {
//check if
if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE) {
//throw exception if email is not valid
throw new customException($email);
}
//check for "example" in mail address
if(strpos($email, "example") !== FALSE) {
throw new Exception("$email is an example e-mail");
}
}
catch (customException $e) {
echo $e->errorMessage();
}
catch(Exception $e) {
echo $e->getMessage();
}
?>
為例進行了說明:
上面的代碼測試兩個條件,並且如果任一條件不滿足拋出異常:
- 該customException()類為舊的例外類的擴展創建。 這樣,它繼承了舊的例外類的所有方法和屬性
- 所述errorMessage()創建功能。 如果電子郵件地址無效,該函數返回一個錯誤信息
- 在$電子郵件變量設置為一個字符串,是一個有效的電子郵件地址,但包含字符串"example"
- 在"try"塊被執行,一個異常沒有拋出的第一個條件
- 由於電子郵件包含字符串的第二個條件觸發的異常"example"
- 的"catch"塊捕捉異常並顯示正確的錯誤消息
如果拋出的異常是類customException並沒有customException抓,只有基本異常捕獲,異常將在那裡處理。
重新拋出異常
有時,當拋出一個異常,你可能希望以不同的方式處理它比標準的方式。 它可以拋出一個異常內的第二次"catch"塊。
腳本應該對用戶隱藏系統錯誤。 系統錯誤可能是編碼器很重要,但不感興趣的用戶。 為了讓事情變得更容易為用戶,您可以重新引發與用戶友好的消息的異常:
<?php
class customException extends Exception {
public function errorMessage() {
//error message
$errorMsg = $this->getMessage().' is not a valid E-Mail address.';
return $errorMsg;
}
}
$email = "[email protected]";
try {
try {
//check for "example" in mail address
if(strpos($email, "example") !== FALSE) {
//throw exception if email is not valid
throw new Exception($email);
}
}
catch(Exception $e) {
//re-throw exception
throw new customException($email);
}
}
catch (customException $e) {
//display custom message
echo $e->errorMessage();
}
?>
為例進行了說明:
上述測試的代碼,如果電子郵件地址包含字符串"example"在裡面,如果這樣做,異常被重新拋出:
- 該customException()類為舊的例外類的擴展創建。 這樣,它繼承了舊的例外類的所有方法和屬性
- 所述errorMessage()創建功能。 如果電子郵件地址無效,該函數返回一個錯誤信息
- 在$電子郵件變量設置為一個字符串,是一個有效的電子郵件地址,但包含字符串"example"
- 在"try"塊包含另一個"try"塊,使之可能重新拋出異常
- 被觸發的異常,因為電子郵件包含字符串"example"
- 在"catch"塊捕獲該異常,並重新拋出一個"customException"
- 所述"customException"被捕獲並顯示錯誤消息
如果該異常不能在其目前陷入"try"塊,它將搜索在catch塊"higher levels" 。
設置頂層異常處理
所述set_exception_handler()函數將用戶定義的函數來處理所有的未捕獲的異常。
<?php
function myException($exception)
{
echo "<b>Exception:</b> " . $exception->getMessage();
}
set_exception_handler('myException');
throw new Exception('Uncaught Exception occurred');
?>
以上代碼的輸出應該是這樣的:
Exception: Uncaught Exception occurred
在上面的代碼沒有"catch"塊。 取而代之的是,頂層異常處理觸發。 此功能可用於捕捉未捕獲的異常。
規則的例外
- 代碼可以在try塊包圍,以幫助捕捉到潛在的異常
- 每個try塊或"throw"必須至少有一個與之對應的catch
- 多個catch可以用來捕獲不同的類的例外
- 異常可以被拋出(or re-thrown)在catch塊try塊內
一個簡單的規則:如果你扔東西,你必須抓住它。