### PHP錯誤機制
在 PHP 中,默認的錯誤處理很簡單。一條消息會被發送到瀏覽器,這條消息帶有文件名、行號以及一條描述錯誤的消息。在創建腳本和 web 應用程序時,錯誤處理是一個重要的部分。如果您的代碼缺少錯誤檢測編碼,那么程序看上去很不專業,也為安全風險敞開了大門。
### ?PHP 中一些最為重要的錯誤檢測方法。
-
簡單的 "die()" 語句
~~~
if(!file_exists("../func.php")){
die("文件不存在<br/>");
} else {
$fp=fopen("../func.php","r");
echo "文件打開成功<br/>";
//..關閉
fclose($fp);
}???
~~~
-
更簡潔的方式
~~~
file_exists("func.php") or die("文件不存在<br/>");
~~~
這句相當于把上面的if...else合并到一起了!
-
創建自定義錯誤檢測機制
看下面的代碼,假設文件是不存的運行的時候會報錯如下:
~~~
<?php
$file=fopen("welcome.txt","r");
?>
~~~
錯誤信息如下(PHP默認的錯誤處理機制):
~~~
Warning: fopen(welcome.txt) [function.fopen]: failed to open stream:
No such file or directory in C:\webfolder\test.php on line 2
~~~
創建一個自定義的錯誤處理器非常簡單。我們很簡單地創建了一個專用函數,可以在 PHP 中發生錯誤時調用該函數。該函數必須有能力處理至少兩個參數 (error level 和 error message),但是可以接受最多五個參數(可選的:file, line-number 以及 error context):
###系統自帶的錯誤函數:
~~~
error_function(error_level,error_message,error_file,error_line,error_context)
~~~
參數分析:
<table class="dataintable "><tbody><tr><th>參數</th><th>描述</th></tr><tr><td>error_level</td><td><p>必需。為用戶定義的錯誤規定錯誤報告級別。必須是一個值數。</p><p>參見下面的表格:錯誤報告級別。</p></td></tr><tr><td>error_message</td><td>必需。為用戶定義的錯誤規定錯誤消息。</td></tr><tr><td>error_file</td><td>可選。規定錯誤在其中發生的文件名。</td></tr><tr><td>error_line</td><td>可選。規定錯誤發生的行號。</td></tr><tr><td>error_context</td><td>可選。規定一個數組,包含了當錯誤發生時在用的每個變量以及它們的值。</td></tr></tbody></table>
### 錯誤報告級別
這些錯誤報告級別是錯誤處理程序旨在處理的錯誤的不同的類型:
<table class="dataintable "><tbody><tr><th>值</th><th>常量</th><th>描述</th></tr><tr><td>2</td><td>E_WARNING</td><td>非致命的 run-time 錯誤。不暫停腳本執行。</td></tr><tr><td>8</td><td>E_NOTICE</td><td><p>Run-time 通知。</p><p>腳本發現可能有錯誤發生,但也可能在腳本正常運行時發生。</p></td></tr><tr><td>256</td><td>E_USER_ERROR</td><td>致命的用戶生成的錯誤。這類似于程序員使用 PHP 函數 trigger_error() 設置的 E_ERROR。</td></tr><tr><td>512</td><td>E_USER_WARNING</td><td>非致命的用戶生成的警告。這類似于程序員使用 PHP 函數 trigger_error() 設置的 E_WARNING。</td></tr><tr><td>1024</td><td>E_USER_NOTICE</td><td>用戶生成的通知。這類似于程序員使用 PHP 函數 trigger_error() 設置的 E_NOTICE。</td></tr><tr><td>4096</td><td>E_RECOVERABLE_ERROR</td><td>可捕獲的致命錯誤。類似 E_ERROR,但可被用戶定義的處理程序捕獲。(參見 set_error_handler())</td></tr><tr><td>8191</td><td>E_ALL</td><td><p>所有錯誤和警告,除級別 E_STRICT 以外。</p><p>(在 PHP 6.0,E_STRICT 是 E_ALL 的一部分)</p></td></tr></tbody></table>
### 錯誤報告級別
這些錯誤報告級別是錯誤處理程序旨在處理的錯誤的不同的類型:
<table class="dataintable "><tbody><tr><th>值</th><th>常量</th><th>描述</th></tr><tr><td>2</td><td>E_WARNING</td><td>非致命的 run-time 錯誤。不暫停腳本執行。</td></tr><tr><td>8</td><td>E_NOTICE</td><td><p>Run-time 通知。</p><p>腳本發現可能有錯誤發生,但也可能在腳本正常運行時發生。</p></td></tr><tr><td>256</td><td>E_USER_ERROR</td><td>致命的用戶生成的錯誤。這類似于程序員使用 PHP 函數 trigger_error() 設置的 E_ERROR。</td></tr><tr><td>512</td><td>E_USER_WARNING</td><td>非致命的用戶生成的警告。這類似于程序員使用 PHP 函數 trigger_error() 設置的 E_WARNING。</td></tr><tr><td>1024</td><td>E_USER_NOTICE</td><td>用戶生成的通知。這類似于程序員使用 PHP 函數 trigger_error() 設置的 E_NOTICE。</td></tr><tr><td>4096</td><td>E_RECOVERABLE_ERROR</td><td>可捕獲的致命錯誤。類似 E_ERROR,但可被用戶定義的處理程序捕獲。(參見 set_error_handler())</td></tr><tr><td>8191</td><td>E_ALL</td><td><p>所有錯誤和警告,除級別 E_STRICT 以外。</p><p>(在 PHP 6.0,E_STRICT 是 E_ALL 的一部分)</p></td></tr></tbody></table>
### 下面是我們自己實現的錯誤處理函數:
~~~
<?php
//自定義自己的錯誤處理函數
function myerror($errno,$errstr){
echo "<font size='5' color='red'>$errno</font><br/>";
echo "錯誤信息:".$errstr;
}
//這里我們還需要改寫set_error_handler
/*PHP 的默認錯誤處理程序是內建的錯誤處理程序。我們打算把上面的函數改造為腳本運行期間的默認錯誤處理程序。set_error_handler() 僅需要一個參數,可以添加第二個參數來規定錯誤級別。
*/
set_error_handler("myerror",);
echo($test);
/*輸出下面的內容:
8
錯誤信息:Undefined variable: test
*/
?>
~~~
###錯誤觸發器:
錯誤觸發器和錯誤處理器區別:觸發器往往處理邏輯上的錯誤,處理器處理系統上的錯誤:
看下面的需求:當輸入年齡大于120時,會觸發錯誤!
~~~
$age = 200;
if($age>120){
trigger_error("the age is logger!",E_USER_WARNING);
exit();
}
~~~
運行上面的代碼會出現下面的錯誤:
~~~
**Warning**: the age is logger! in?/var/myphp/exec/File.php?on line?3
~~~
看處理器一樣,上面的警告信息是系統打印出來的。那么我們將處理器和錯誤觸發器共同使用,看下面的代碼:
###
~~~
<?php //自定義自己的錯誤處理函數
function myerror($errno,$errstr){
echo "<font size='5' color='red'>$errno</font><br/>";
echo "錯誤信息:".$errstr;
}
//指定錯誤的處理函數,
set_error_handler("myerror",E_USER_WARNING);
$age = 200;
if($age>120){
//E_USER_WARNING 這里必須和制定錯誤處理函數對應,否則還是會調用系統錯誤處理函數
trigger_error("the age is logger!",E_USER_WARNING);
exit();
}
/*512
錯誤信息:the age is logger!
*/
?>
~~~
### 可能的錯誤類型:
- E_USER_ERROR - 致命的用戶生成的 run-time 錯誤。錯誤無法恢復。腳本執行被中斷。
- E_USER_WARNING - 非致命的用戶生成的 run-time 警告。腳本執行不被中斷。
- E_USER_NOTICE - 默認。用戶生成的 run-time 通知。腳本發現了可能的錯誤,也有可能在腳本運行正常時發生。
### ?錯誤日志:
[http://blog.csdn.net/heiyeshuwu/article/details/577838](http://blog.csdn.net/heiyeshuwu/article/details/577838)?這個博客有介紹,可以看看!
默認地,根據在PHP.ini中的error_log配置,PHP想服務器的錯誤記錄系統或者文件發送錯誤日志,通過使用error_log()函數,您可以向指定的文件或遠程目的地發送錯誤記錄
~~~
bool error_log ( string message [, int message_type [, string destination [, string extra_headers]]] )
~~~
~~~
<?php
//設置時區
date_default_timezone_set("Asia/Chongqing");
//自定義自己的錯誤處理函數
function myerror($errno,$errstr){
$error_info="錯誤信息:".$errno.$errstr;
error_log(date("Y-m-d G-i-s").$error_ingo."\r\n",3,"1.txt");
}
set_error_handler("myerror",E_USER_WARNING);
$age = 200;
if($age>120){
trigger_error("the age is logger!",E_USER_WARNING);
exit();
}
?>
~~~
### 二、PHP異常處理【重點】
### 基本語法:
~~~
try{
? ? ? ? ? //可能出現錯誤或異常的代碼
? ? ? ? ? //catch 捕獲 ?Exception是php已定義好的異常類
? ? ? } catch(Exception $e){
? ? ? ? ? //對異常處理,方法:
? ? ? ? ? ? ? //1、自己處理
? ? ? ? ? ? ? //2、不處理,將其再次拋出
? ? ? }
~~~
處理處理程序應當包括:
1. Try?- 使用異常的函數應該位于 "try"??代碼塊內。如果沒有觸發異常,則代碼將照常繼續執行。但是如果異常被觸發,會拋出一個異常。
1. Throw - 這里規定如何觸發異常。每一個 "throw" 必須對應至少一個 "catch"
1. Catch - "catch" 代碼塊會捕獲異常,并創建一個包含異常信息的對象 ??
看下面的例子:
~~~
<?php
//創建一個拋出異常的函數
function checkNum($number){
if($number >1){
throw new Exception("Value must be 1 or little!<br/>");
}
return true;
}
//在 try 代碼塊中觸發異常
try{
$num = 2;
checkNum($num);//AAAA
echo "如何拋出異常,這個將不會被執行!<br/>";
}catch(Exception $e){
//捕獲異常
echo 'Message:'.$e->getMessage();
}
echo "繼續執行<br/>";
?>
~~~
當$num=2;將會拋開異常,打印下面的語句:
Message:Value must be 1 or little!
繼續執行
**當$num=0;將會拋開異常,打印下面的語句:**
**如何拋出異常,這個將不會被執行!
繼續執行**
從上面可以得出下面的結論:
1、出捕獲異常并不會干擾下面代碼的執行!
2、如果異常拋出,其后面的語句將不會被執行;
看下面的代碼我們自己設置定義異常處理函數:
~~~
<?php
function my_exception($e){
echo "我是頂級處理器:".$e->getMessage.$e->getline;
}
//修改默認的頂級異常處理函數
set_exception_handler("my_exception");
function a1($val){
if($val>100){
//拋出異常
throw new Exception("val > 100!<br/>");
}
}
function a2($val){
if($val=="jsh"){
//拋出異常
throw new Exception("val jsh!<br/>");
}
}
try{
a2("jsh");//這是會拋出異常
}catch(Exception $e){
//獲取異常
echo $e->getMessage();
//可以繼續拋出,這是會啟動PHP默認的異常處理機制
//我們可以自己定義一個頂級異常處理函數
throw $e;
}
?>
~~~
### 異常的規則:
1、需要進行異常處理的代碼放入try代碼塊內,以便捕獲潛在的異常。
2、每個try或者,throw代碼塊至少擁有一個catch代碼。
3、使用多個catch代碼塊可以捕獲不同種類的異常。
~~~
?try{
? ? ? XXXXXX;
?}catch(my_exception $e){//自己定義的異常處理函數
? ? ? XXXXXX;
?}catch(Exception $3){//系統自帶的異常處理函數
? ? ? XXXXX;
? }?
~~~
4、可以在try代碼塊中再次拋出異常
5,如果拋出了異常,就必須捕獲他,獲知使用頂級異常處理機制。
看下面的代碼示例,是在PHP手冊中的,仔細獲得下吧
~~~
<?php
/**
* 自定義一個異常處理類
*/
class MyException extends Exception
{
// 重定義構造器使 message 變為必須被指定的屬性
public function __construct($message, $code = 0) {
// 自定義的代碼
// 確保所有變量都被正確賦值
parent::__construct($message, $code);
}
// 自定義字符串輸出的樣式 */
public function __toString() {
return __CLASS__ . ": [{$this->code}]: {$this->message}\n";
}
public function customFunction() {
echo "A Custom function for this type of exception\n";
}
}
/**
* 創建一個用于測試異常處理機制的類
*/
class TestException
{
public $var;
const THROW_NONE = 0;
const THROW_CUSTOM = 1;
const THROW_DEFAULT = 2;
function __construct($avalue = self::THROW_NONE) {
switch ($avalue) {
case self::THROW_CUSTOM:
// 拋出自定義異常
throw new MyException('1 is an invalid parameter', 5);
break;
case self::THROW_DEFAULT:
// 拋出默認的異常
throw new Exception('2 isnt allowed as a parameter', 6);
break;
default:
// 沒有異常的情況下,創建一個對象
$this->var = $avalue;
break;
}
}
}
// 例子 1
try {
$o = new TestException(TestException::THROW_CUSTOM);
} catch (MyException $e) { // 捕獲異常
echo "Caught my exception:<br/>", $e;
$e->customFunction();
} catch (Exception $e) { // 被忽略
echo "Caught Default Exception:<br/>", $e;
}
/*
// 執行后續代碼
var_dump($o);
echo "<br/>";
// 例子 2
try {
$o = new TestException(TestException::THROW_DEFAULT);
} catch (MyException $e) { // 不能匹配異常的種類,被忽略
echo "Caught my exception\n", $e;
$e->customFunction();
} catch (Exception $e) { // 捕獲異常
echo "Caught Default Exception\n", $e;
}
// 執行后續代碼
var_dump($o);
echo "<br/>";
// 例子 3
try {
$o = new TestException(TestException::THROW_CUSTOM);
} catch (Exception $e) { // 捕獲異常
echo "Default Exception caught\n", $e;
}
// 執行后續代碼
var_dump($o);
echo "<br/>";
// 例子 4
try {
$o = new TestException();
} catch (Exception $e) { // 沒有異常,被忽略
echo "Default Exception caught\n", $e;
}
*/
// 執行后續代碼
var_dump($o);
echo "<br/>";
?>
~~~
- 前言
- HTML(第一天)
- HTML(第二天)
- DIV+CSS(第一天)
- DIV+CSS(第二天)
- DIV+CSS(第三天)
- DIV+CSS(第四天)
- PHP開發環境配置說明
- PHP基礎數據類型及運算符介紹
- 走進PHP函數
- 走進位運算
- 走進數組及相關數組函數
- 面向對象的編程(類與對象)
- 面向對象的編程(類成員方法用法)
- 構造方法,析構方法
- static,global用法
- 靜態方法
- 面向對象的編程方法
- 接口方法
- 接口VS繼承、final、const
- 錯誤及異常處理機制、錯誤日志
- HTTP協議深度剖析
- 文件下載
- PHP數據庫編程
- 數據庫編程(2)
- 超全局變量
- Zend studio 開發環境入門
- 雇員管理系統(1)
- 雇員管理系統(2)
- 會話技術(cookie session)
- 會話技術 session場景使用介紹!
- PHP.in中session和cookie的配置說明
- PHP文件編程
- 報表及繪圖技術
- 報表及繪圖技術(jpgraph庫使用,Linux安裝及配置說明)
- XML基本語法及DTD介紹
- XML編程(Dom技術)
- XML編程(Xpath技術,simpleXml技術)基礎入門
- 網上支付平臺PHP版本
- javascript基礎入門