標籤:處理器 邏輯 blog 預設 代碼 else row trigger and
在編寫php程式時,錯誤處理是一個重要的部分。如果程式中缺少錯誤偵測代碼,那麼看上去很不專業,也為安全風險敞開了大門
例:<?php $a = fopen(‘test.txt‘,‘r‘); //這裡並沒有對檔案進行判斷就開啟了,如果檔案不存在就會報錯?> 那麼正確的寫法應該如下:<?php if(file_exists(‘test.txt‘)){ $f=fopen(‘test.txt‘,‘r‘); //使用完後關閉 fclose($f); } ?> 一、PHP錯誤處理的三種方式A、簡單的die()語句; 等價於exit();例: if(!file_exists(‘aa.txt‘)){ die(‘檔案不存在‘); } else { //執行操作 } //如果上面die()被觸發,那麼這裡echo接不被執行 echo ‘ok‘; 簡潔寫法: file_exits(‘aaa.txt‘) or die(‘檔案不存在‘); echo ‘ok‘; B、自訂錯誤和錯誤觸發器
1、錯誤處理器(自訂錯誤,一般用於語法錯誤處理) 建立自訂錯誤函數(處理器),該函數必須有能力處理至少兩個參數(error_level和errormessage),但是可以接受最多五個參數(error_file、error_line、error_context) 文法: function error_function($error_level,$error_message,$error_file,$error_line,$error_context) //建立好後還需要改寫set_error_handler();函數 set_error_handler(‘error_function‘,E_WARNING);//這裡error_function對應上面建立的自訂處理器名,第二個參數為使用自訂錯誤處理器的錯誤層級;錯誤報表層級(瞭解即可)
這些錯誤報表層級是錯誤處理程式旨在處理的錯誤的不同的類型:
值 |
常量 |
描述 |
2 |
E_WARNING |
非致命的 run-time 錯誤。不暫停指令碼執行。 |
8 |
E_NOTICE |
Run-time 通知。 指令碼發現可能有錯誤發生,但也可能在指令碼正常運行時發生。 |
256 |
E_USER_ERROR |
致命的使用者產生的錯誤。這類似於程式員使用 PHP 函數 trigger_error() 設定的 E_ERROR。 |
512 |
E_USER_WARNING |
非致命的使用者產生的警告。這類似於程式員使用 PHP 函數 trigger_error() 設定的 E_WARNING。 |
1024 |
E_USER_NOTICE |
使用者產生的通知。這類似於程式員使用 PHP 函數 trigger_error() 設定的 E_NOTICE。 |
4096 |
E_RECOVERABLE_ERROR |
可捕獲的致命錯誤。類似 E_ERROR,但可被使用者定義的處理常式捕獲。(參見 set_error_handler()) |
8191 |
E_ALL |
所有錯誤和警告,除層級 E_STRICT 以外。 (在 PHP 6.0,E_STRICT 是 E_ALL 的一部分) |
2、錯誤觸發器(一般用於處理邏輯上的錯誤)
需求:比如要接收一個年齡,如果數字大於120,就認為是一個錯誤傳統方法:
if($age>120){
echo ‘年齡錯誤‘;exit();
}
使用觸發器: if($age>120){ //trigger_error(‘錯誤資訊‘[,‘錯誤等級‘]);這裡錯誤等級為可選項,用於定義該錯誤的層級 //使用者定義的層級包含以下三種:E_USER_WARNING 、E_USER_ERROR 、E_USER_NOTICE trigger_error(‘年齡錯誤‘);//這裡是調用的系統預設的錯誤處理方式,我們也可以用自訂處理器 } //自訂處理器,與上面相同 function myerror($error_level,$error_message){ echo ‘error text‘; } //同時需要改變系統預設的處理函數 set_error_handler(‘myerror‘,E_USER_WARNING);//同上面,第一個參數為自訂函數的名稱,第二個為錯誤層級【這裡的錯誤層級通常為以下三種:E_USER_WARNING 、E_USER_ERROR 、E_USER_NOTICE】 //現在再使用trigger_error就可以使用自訂的錯誤處理函數了 練習題:
1 <?php 2 date_default_timezone_set(‘PRC‘); 3 function myerror($error_level,$error_message){ 4 $info= "錯誤號碼:$error_level\n"; 5 $info.= "錯誤資訊:$error_message\n"; 6 $info.= ‘發生時間:‘.date(‘Y-m-d H:i:s‘); 7 $filename=‘aa.txt‘; 8 if(!$fp=fopen($filename,‘a‘)){ 9 ‘建立檔案‘.$filename.‘失敗‘;10 }11 if(is_writeable($filename)){12 if(!fwrite($fp,$info)){13 echo ‘寫入檔案失敗‘;14 } else {15 echo ‘已成功記錄錯誤資訊‘;16 }17 fclose($fp);18 } else {19 echo ‘檔案‘.$filename.‘不可寫‘;20 }21 exit();22 }23 set_error_handler(‘myerror‘,E_WARNING);24 $fp=fopen(‘aaa.txt‘,‘r‘);25 ?>
C、錯誤記錄檔 預設的根據php.ini中error_log配置,php向伺服器的錯誤記錄系統或檔案發送錯誤記錄。通過使用error_log()函數可以向檔案或遠程目的地發送錯誤記錄; 文法: error_log(error[,type,destination,headers]) type部分一般用3,表示在檔案後面追加錯誤資訊,而不會覆蓋原內容 destination表示目的地,即存放的檔案或遠程目的地 如:error_log("$error_info",3,"errors.txt"); 二、PHP異常處理【重點】 1、基本文法 try{ //可能出現錯誤或異常的代碼 //catch 捕獲 Exception是php已定義好的異常類 } catch(Exception $e){ //對異常處理,方法: //1、自己處理 //2、不處理,將其再次拋出 }2、處理處理常式應當包括:
- Try - 使用異常的函數應該位於 "try" 代碼塊內。如果沒有觸發異常,則代碼將照常繼續執行。但是如果異常被觸發,會拋出一個異常。
- Throw - 這裡規定如何觸發異常。每一個 "throw" 必須對應至少一個 "catch"
- Catch - "catch" 代碼塊會捕獲異常,並建立一個包含異常資訊的對象
讓我們觸發一個異常:
1 <?php 2 //建立可拋出一個異常的函數 3 function checkNum($number){ 4 if($number>1){ 5 throw new Exception("Value must be 1 or below"); 6 } 7 return true; 8 } 9 10 //在 "try" 代碼塊中觸發異常11 try{12 checkNum(2);13 //如果異常被拋出,那麼下面一行代碼將不會被輸出14 echo ‘If you see this, the number is 1 or below‘;15 }catch(Exception $e){16 //捕獲異常17 echo ‘Message: ‘ .$e->getMessage();18 }19 ?>
上面代碼將獲得類似這樣一個錯誤:
Message: Value must be 1 or below
例子解釋:
上面的代碼拋出了一個異常,並捕獲了它:
- 建立 checkNum() 函數。它檢測數字是否大於 1。如果是,則拋出一個異常。
- 在 "try" 代碼塊中調用 checkNum() 函數。
- checkNum() 函數中的異常被拋出
- "catch" 代碼塊接收到該異常,並建立一個包含異常資訊的對象 ($e)。
- 通過從這個 exception 對象調用 $e->getMessage(),輸出來自該異常的錯誤訊息
不過,為了遵循“每個 throw 必須對應一個 catch”的原則,可以設定一個頂層的異常處理器來處理漏掉的錯誤。
set_exception_handler()函數可設定處理所有未捕獲異常的使用者定義函數
//設定一個頂級異常處理器
function myexception($e){
echo ‘this is top exception‘;
} //修改預設的異常處理器
set_exception_handler("myexception");
try{
$i=5;
if($i<10){
throw new exception(‘$i must greater than 10‘);
}
}catch(Exception $e){
//處理異常
echo $e->getMessage().‘<br/>‘;
//不處理異常,繼續拋出
throw new exception(‘errorinfo‘); //也可以用throw $e 保留原錯誤資訊;
}
建立一個自訂的異常類
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;
}
}
//使用
try{
throw new customException(‘error message‘);
}catch(customException $e){
echo $e->errorMsg();
}
可以使用多個catch來返回不同情況下的錯誤資訊
try{
$i=5;
if($i>0){
throw new customException(‘error message‘);//使用自訂異常類處理
} if($i<-10){
throw new exception(‘error2‘);//使用系統預設異常處理
}
}catch(customException $e){
echo $e->getMessage();
}catch(Exception $e1){
echo $e1->getMessage();
}
異常的規則
- 需要進行異常處理的代碼應該放入 try 代碼塊內,以便捕獲潛在的異常。
- 每個try或throw代碼塊必須至少擁有一個對應的 catch 代碼塊。
- 使用多個 catch 代碼塊可以捕獲不同種類的異常。
- 可以在try代碼內的catch 代碼塊中再次拋出(re-thrown)異常。
PHP中的錯誤和異常處理