第1章 錯誤報告級別
PHP 程式的錯誤一般歸屬於下列三個領域:
語法錯誤:
語法錯誤最常見,並且也容易修復。如:程式碼中遺漏一個分號。這類錯誤會阻止指令碼的執行。
執行時錯誤:
這種錯誤一般不會阻止PHP指令碼的執行,但會阻止當前要做的事情。輸出一條錯誤,但php指令碼繼續執行。
邏輯錯誤:
這種錯誤最麻煩,既不阻止指令碼執行,也不輸出錯誤訊息。
圖解 Apache Web 伺服器與 PHP 引擎的關係。
案例:
//語法錯誤,忘記加分號
echo "123"
//執行時錯誤
echo '123';
function laowang(){
echo '456';
}
laoliu();
//邏輯錯誤,想要輸出隔壁老王,結果出現的是帽子,在系統角度看,這並不是錯誤。
if(1==1){
echo "帽子";
}else{
echo "隔壁老王";
}
在 PHP 系統中,到底有哪些錯誤報告級別?
在 php.ini 中可以找到錯誤級別的說明和設定。
//表示開啟所有錯誤提示但遮蔽NOTICE錯誤
error_reporting = E_ALL & ~E_NOTICE
//直接關閉所有錯誤提示,開發階段一般是on,但上線以後一般會選擇off
display_errors = off/on
級別常量 | 錯誤值 | 錯誤報告描述 |
---|---|---|
E_ERROR | 1 | 致命的執行時錯誤(阻止指令碼執行) |
E_WARNING | 2 | 執行時警告(非致命性錯誤) |
E_PARSE | 4 | 從語法中解析錯誤 |
E_NOTICE | 8 | 執行時注意訊息(可能是或可能不是一個問題) |
E_CORE_ERROR | 16 | PHP啟動時初始化過程中的致命錯誤 |
E_CORE_WARNING | 32 | PHP啟動時初始化過程中的警告(非致命性錯) |
E_COMPILE_ERROR | 64 | 編譯時致命性錯 |
E_COMPILE_WARNING | 128 | 編譯時警告(非致命性錯) |
E_USER_ERROR | 256 | 使用者自定義的致命錯誤 |
E_USER_WARNING | 512 | 使用者自定義的警告(非致命性錯誤) |
E_USER_NOTICE | 1024 | 使用者自定義的提醒(經常是bug) |
E_STRICT | 2048 | 編碼標準化警告(建議如何修改以向前相容) |
E_ALL | 6143 | 所有的錯誤、警告和注意資訊 |
//錯誤值一般都是系統定義好的常量
echo E_ERROR; //1
//1 2 4 8 ... 6143原理
//利用的二進位制,採用亮燈的原理,錯了就亮。
//000000000001 ---> 就是第一個錯誤
在實際的開發中,沒有人關注什麼錯誤級別錯誤值什麼的,報錯了,看一眼大概啥型別的,直接找BUG就行了。
在實際的開發中,我們其實需要做大量的錯誤處理,寫功能比較容易,無非就是增刪改查,就像汽車,讓一輛汽車開起來並不難,但如果要做各種安全防護,就要麻煩的多,考慮的因素也非常多,說明書厚的跟字典一樣。
第2章 調整錯誤報告級別
動態設定 PHP 錯誤資訊是否輸出,只在當前指令碼生效,並不會影響php.ini全域性的設定。
-
display_errors: 是否開啟PHP輸出錯誤報告的功能。
值為:On(預設輸出錯誤報告)、 Off(遮蔽所有錯誤資訊)
在PHP指令碼中可呼叫ini_set( )函式,動態設定php.ini配置檔案.
如:ini_set("display_errors","On"); //顯示所有錯誤資訊
//設定是否輸出錯誤資訊 ini_set('display_errors',"off");//關閉 ini_set('display_errors',"on");//開啟 ini_set('display_errors',0);//關閉 ini_set('display_errors',1);//開啟 //呼叫函式進行試驗 aa();
error_reporting: 設定不同的錯誤報告級別。
error_reporting = E_ALL & ~E_NOTICE
-- 可以丟擲任何非注意的錯誤,預設值。
error_reporting = E_ERROR | E_PARSE | E_CORE_ERROR
-- 只考慮致命的執行時錯誤、新解析錯誤和核心錯誤。
error_reporting = E_ALL & ~(E_USER_ERROR | E_USER_WARNING | E_USER_NOTICE)
-- 報告除使用者導致的錯誤之外的所有錯誤。
在PHP指令碼可以透過error_reporting( )函式動態設定錯誤報告級別。如:error_reporting(E_ALL);
//動態設定錯誤等級
error_reporting(E_ALL);
//試驗,報所有錯誤
echo $a;
//開啟除了notice以外的所有錯誤
error_reporting(E_ALL & ~E_NOTICE);
echo $a;
案例:
ini_set('display_errors',1);//開啟
error_reporting(E_ALL);//開啟所有錯誤
$sum=0;//此處如果遮蔽掉,初次使用sum時,變數未定義會notice報錯
for($i=0;$i<=10;$i++){
$sum+=$i;
}
echo $sum;
strlen();//字串長度函式,不給引數,報warning警告錯誤,不會影響程式執行
echo "aaaaaaaa";
aa();//致命錯誤,呼叫一個不存在的函式時程式會終止執行。
php.ini 中錯誤設定選項(瞭解即可,無需深究)。
配置指令 | 預設值 | 描述 |
---|---|---|
display_startup_errors | Off | 是否顯示PHP引擎在初始化時遇到的錯誤 |
log_errors | Off | 確定日誌語句記錄位置 |
error_log | Null | 設定錯誤可以傳送到syslog中 |
log_errors_max_len | 1024 | 每個日誌項的最大長度,以位元組為單位,設定0表示指定最大長度。 |
ignore_repeated_errors | Off | 是否忽略同一個檔案、同一行發生的重複錯誤訊息 |
ignore_repeated_source | Off | 忽略不同檔案中和同一檔案中不同行發生的重複錯誤。 |
track_errors | Off | 啟動該指令會使PHP在$php_errormsg中儲存最近發生的錯誤資訊。 |
第3章 PHP 日誌的記錄方式
1)採用檔案記錄 (推薦使用)。
2) 錯誤日誌記錄到作業系統日誌中。
思考:為什麼要做日誌記錄?
1.方便自己開發的時候查詢,框架一般都自帶日誌功能,只需要開啟就OK。
2.可以藉助執行日誌開發相應的後臺日誌功能,給管理員查詢,方便管理。
3.1 採用檔案記錄
先配置 php.ini 檔案
error_reporting = E_ALL //將向PHP傳送每個錯誤
display_errors=Off //不顯示錯誤報告
* log_errors=On //決定日誌語句記錄的位置
log_errors_max_len=1024 //每個日誌項的最大長度
* error_log=G:/myerror.log //指定錯誤寫進的檔案
試驗:
a();//注意觀察日誌檔案
conunt();//注意觀察日誌檔案
以上記錄的是系統報錯的日誌。
思考:我能不能做一個使用者操作的人為的日誌?
使用函式:在 PHP 檔案中使用 error_log() 來記錄日誌,就可以將資訊寫入到 myerror.log 檔案中。
error_log("使用者xxx想刪除ID為69的使用者名稱,已經記錄到日誌,請注意這個小子");
引數參考手冊。
rigger_error() 函式記錄日誌
上一節中,我們使用error_log()報一個自定義的錯誤資訊,讓系統記錄,只記錄資訊。
而使用 trigger_error() 比 error_log 更加靈活一些,可指定等級和檔案位置。
//可利用系統提供的錯誤等級給日誌記錄自己定義好的錯誤資訊,預設為notic級別
trigger_error("使用者xxx想刪除ID為69的使用者名稱,已經記錄到日誌,請注意這個小子",E_USER_ERROR);
3.2 錯誤日誌記錄到作業系統日誌中
先配置 php.ini 檔案
error_reporting = E_ALL //將向PHP傳送每個錯誤
* display_errors=Off //不顯示錯誤報告
* log_errors=On //決定日誌語句記錄的位置
log_errors_max_len=1024 //每個日誌項的最大長度
* error_log=syslog //指定錯誤寫進的檔案
使用四個函式來記錄日誌:
//define_syslog_variables(); 為系統日誌初始化配置
//openlog(); 開啟一個日誌連結
//syslog(); 傳送一條日誌記錄
//closelog(); 關閉日誌連結
試驗:
aa();//不再顯示日誌,而是記錄到系統日誌中去了。
目前的開發已經淘汰這種方式,4個函式必須同時使用,課後可自行試驗,程式碼如下:
define_syslog_variables();
openlog("PHP5", LOG_PID , LOG_USER);
syslog(LOG_WARNING, "警告報告向syslog中傳送的演示,警告時間: ".date("Y/m/d H:i:s"));
closelog();
如何檢視 Window 系統日誌。
計算機右鍵 ---> 管理(G) ---> 系統工具 ---> 事件檢視器 ---> Windows 日誌 ---> 應用程式
第4章 自定義錯誤處理
自定義錯誤報告的處理方式,可以完全繞過標準的PHP錯誤處理函式,這樣就可以按自己定義的格式列印錯誤報告,或改變錯誤報告列印的位置。
說白了就是不使用系統的錯誤提示,改為自己的。
set_error_handler() -- 設定使用者自定義錯誤處理。
引數:mixed set_error_handler ( callable $error_handler
[, int $error_types
= E_ALL | E_STRICT ] )
回撥函式:回來調取函式。
所謂的回撥函式:
function demo(){
return "我才不要呢";
}
function demo2(){
return "我也不要";
}
function result($suan){
return $suan();
}
//將函式名demo1 函式名demo2 作為字串引數傳遞給result函式,那麼可以自動呼叫上面的函式,我們就說demo1,demo2是result的回撥函式
echo result('demo2');
案例:
//回撥函式也需要引數接收,參考手冊
/*
errno
第一個引數 errno,包含了錯誤的級別,是一個 integer。
errstr
第二個引數 errstr,包含了錯誤的資訊,是一個 string。
errfile
第三個引數是可選的,errfile, 包含了發生錯誤的檔名,是一個 string。
errline
第四個引數是一個可選項, errline, 包含了錯誤發生的行號,是一個 integer。
*/
function callbackset($errno,$errstr,$errfile,$errline){
echo "自定義錯誤處理:錯誤級別:{$errno},錯誤資訊是:{$errstr}.所在檔案:{$errfile}的第{$errline}行";
}
set_error_handler("callbackset");//此處設定為報錯的返回資訊交給callbackset自行處理
echo $aa;
特別注意:E_ERROR、E_PARSE、E_CORE_ERROR、E_CORE_WARNING、E_COMPILE_ERROR、E_COMPILE_WARNING是不會有效果的,通常會用原始的方式顯示。
本作品採用《CC 協議》,轉載必須註明作者和本文連結