常用模塊之錯(cuò)誤處理

第1章 錯(cuò)誤報(bào)告級別

PHP 程序的錯(cuò)誤一般歸屬于下列三個(gè)領(lǐng)域:

語法錯(cuò)誤:

語法錯(cuò)誤最常見,并且也容易修復(fù)。如:代碼中遺漏一個(gè)分號。這類錯(cuò)誤會阻止腳本的執(zhí)行。

運(yùn)行時(shí)錯(cuò)誤:

這種錯(cuò)誤一般不會阻止PHP腳本的執(zhí)行,但會阻止當(dāng)前要做的事情。輸出一條錯(cuò)誤,但php腳本繼續(xù)執(zhí)行。

邏輯錯(cuò)誤:

這種錯(cuò)誤最麻煩,既不阻止腳本執(zhí)行,也不輸出錯(cuò)誤消息。

案例:

//語法錯(cuò)誤,忘記加分號
echo "123"   
 
//運(yùn)行時(shí)錯(cuò)誤
echo '123';
function laowang(){
    echo '456';
}

laoliu();

//邏輯錯(cuò)誤,想要輸出隔壁老王,結(jié)果出現(xiàn)的是帽子,在系統(tǒng)角度看,這并不是錯(cuò)誤。
if(1==1){
    echo "帽子";
}else{
    echo "隔壁老王";
}

在 PHP 系統(tǒng)中,到底有哪些錯(cuò)誤報(bào)告級別?

在 php.ini 中可以找到錯(cuò)誤級別的說明和設(shè)置。

//表示打開所有錯(cuò)誤提示但屏蔽NOTICE錯(cuò)誤
error_reporting = E_ALL & ~E_NOTICE 

//直接關(guān)閉所有錯(cuò)誤提示,開發(fā)階段一般是on,但上線以后一般會選擇off
display_errors = off/on    
級別常量 錯(cuò)誤值 錯(cuò)誤報(bào)告描述
E_ERROR 1 致命的運(yùn)行時(shí)錯(cuò)誤(阻止腳本執(zhí)行)
E_WARNING 2 運(yùn)行時(shí)警告(非致命性錯(cuò)誤)
E_PARSE 4 從語法中解析錯(cuò)誤
E_NOTICE 8 運(yùn)行時(shí)注意消息(可能是或可能不是一個(gè)問題)
E_CORE_ERROR 16 PHP啟動(dòng)時(shí)初始化過程中的致命錯(cuò)誤
E_CORE_WARNING 32 PHP啟動(dòng)時(shí)初始化過程中的警告(非致命性錯(cuò))
E_COMPILE_ERROR 64 編譯時(shí)致命性錯(cuò)
E_COMPILE_WARNING 128 編譯時(shí)警告(非致命性錯(cuò))
E_USER_ERROR 256 用戶自定義的致命錯(cuò)誤
E_USER_WARNING 512 用戶自定義的警告(非致命性錯(cuò)誤)
E_USER_NOTICE 1024 用戶自定義的提醒(經(jīng)常是bug)
E_STRICT 2048 編碼標(biāo)準(zhǔn)化警告(建議如何修改以向前兼容)
E_ALL 6143 所有的錯(cuò)誤、警告和注意信息
//錯(cuò)誤值一般都是系統(tǒng)定義好的常量
echo E_ERROR; //1

//1 2 4 8 ... 6143原理
//利用的二進(jìn)制,采用亮燈的原理,錯(cuò)了就亮。
//000000000001 ---> 就是第一個(gè)錯(cuò)誤

在實(shí)際的開發(fā)中,沒有人關(guān)注什么錯(cuò)誤級別錯(cuò)誤值什么的,報(bào)錯(cuò)了,看一眼大概啥類型的,直接找BUG就行了。

在實(shí)際的開發(fā)中,我們其實(shí)需要做大量的錯(cuò)誤處理,寫功能比較容易,無非就是增刪改查,就像汽車,讓一輛汽車開起來并不難,但如果要做各種安全防護(hù),就要麻煩的多,考慮的因素也非常多,說明書厚的跟字典一樣。

第2章 調(diào)整錯(cuò)誤報(bào)告級別

動(dòng)態(tài)設(shè)置 PHP 錯(cuò)誤信息是否輸出,只在當(dāng)前腳本生效,并不會影響php.ini全局的設(shè)置。

  • display_errors: 是否開啟PHP輸出錯(cuò)誤報(bào)告的功能。

    值為:On(默認(rèn)輸出錯(cuò)誤報(bào)告)、 Off(屏蔽所有錯(cuò)誤信息)

    在PHP腳本中可調(diào)用ini_set( )函數(shù),動(dòng)態(tài)設(shè)置php.ini配置文件.

    如:ini_set("display_errors","On"); //顯示所有錯(cuò)誤信息

//設(shè)置是否輸出錯(cuò)誤信息
ini_set('display_errors',"off");//關(guān)閉
ini_set('display_errors',"on");//開啟
ini_set('display_errors',0);//關(guān)閉
ini_set('display_errors',1);//開啟
//調(diào)用函數(shù)進(jìn)行試驗(yàn)
aa();

error_reporting: 設(shè)置不同的錯(cuò)誤報(bào)告級別。

error_reporting = E_ALL & ~E_NOTICE

-- 可以拋出任何非注意的錯(cuò)誤,默認(rèn)值。

error_reporting = E_ERROR | E_PARSE | E_CORE_ERROR

-- 只考慮致命的運(yùn)行時(shí)錯(cuò)誤、新解析錯(cuò)誤和核心錯(cuò)誤。

error_reporting = E_ALL & ~(E_USER_ERROR | E_USER_WARNING | E_USER_NOTICE)

-- 報(bào)告除用戶導(dǎo)致的錯(cuò)誤之外的所有錯(cuò)誤。

在PHP腳本可以通過error_reporting( )函數(shù)動(dòng)態(tài)設(shè)置錯(cuò)誤報(bào)告級別。如:error_reporting(E_ALL);

//動(dòng)態(tài)設(shè)置錯(cuò)誤等級
error_reporting(E_ALL);
//試驗(yàn),報(bào)所有錯(cuò)誤
echo $a;

//開啟除了notice以外的所有錯(cuò)誤
error_reporting(E_ALL & ~E_NOTICE);
echo $a;

案例:

ini_set('display_errors',1);//開啟
error_reporting(E_ALL);//開啟所有錯(cuò)誤

$sum=0;//此處如果屏蔽掉,初次使用sum時(shí),變量未定義會notice報(bào)錯(cuò)
for($i=0;$i<=10;$i++){
    $sum+=$i;
}
echo $sum;


strlen();//字符串長度函數(shù),不給參數(shù),報(bào)warning警告錯(cuò)誤,不會影響程序執(zhí)行
echo "aaaaaaaa";
aa();//致命錯(cuò)誤,調(diào)用一個(gè)不存在的函數(shù)時(shí)程序會終止運(yùn)行。

php.ini 中錯(cuò)誤設(shè)置選項(xiàng)(了解即可,無需深究)。

配置指令 默認(rèn)值 描述
display_startup_errors Off 是否顯示PHP引擎在初始化時(shí)遇到的錯(cuò)誤
log_errors Off 確定日志語句記錄位置
error_log Null 設(shè)置錯(cuò)誤可以發(fā)送到syslog中
log_errors_max_len 1024 每個(gè)日志項(xiàng)的最大長度,以字節(jié)為單位,設(shè)置0表示指定最大長度。
ignore_repeated_errors Off 是否忽略同一個(gè)文件、同一行發(fā)生的重復(fù)錯(cuò)誤消息
ignore_repeated_source Off 忽略不同文件中和同一文件中不同行發(fā)生的重復(fù)錯(cuò)誤。
track_errors Off 啟動(dòng)該指令會使PHP在$php_errormsg中存儲最近發(fā)生的錯(cuò)誤信息。

第3章 PHP 日志的記錄方式

1)采用文件記錄 (推薦使用)。

2) 錯(cuò)誤日志記錄到操作系統(tǒng)日志中。

思考:為什么要做日志記錄?

1.方便自己開發(fā)的時(shí)候查詢,框架一般都自帶日志功能,只需要開啟就OK。

2.可以借助運(yùn)行日志開發(fā)相應(yīng)的后臺日志功能,給管理員查詢,方便管理。

3.1 采用文件記錄

先配置 php.ini 文件

error_reporting = E_ALL     //將向PHP發(fā)送每個(gè)錯(cuò)誤
    display_errors=Off          //不顯示錯(cuò)誤報(bào)告
  * log_errors=On               //決定日志語句記錄的位置
    log_errors_max_len=1024     //每個(gè)日志項(xiàng)的最大長度
  * error_log=G:/myerror.log    //指定錯(cuò)誤寫進(jìn)的文件

試驗(yàn):

a();//注意觀察日志文件
conunt();//注意觀察日志文件

以上記錄的是系統(tǒng)報(bào)錯(cuò)的日志。

思考:我能不能做一個(gè)用戶操作的人為的日志?

使用函數(shù):在 PHP 文件中使用 error_log() 來記錄日志,就可以將信息寫入到 myerror.log 文件中。

error_log("用戶xxx想刪除ID為69的用戶名,已經(jīng)記錄到日志,請注意這個(gè)小子");

參數(shù)參考手冊。

rigger_error() 函數(shù)記錄日志

上一節(jié)中,我們使用error_log()報(bào)一個(gè)自定義的錯(cuò)誤信息,讓系統(tǒng)記錄,只記錄信息。

而使用 trigger_error() 比 error_log 更加靈活一些,可指定等級和文件位置。

//可利用系統(tǒng)提供的錯(cuò)誤等級給日志記錄自己定義好的錯(cuò)誤信息,默認(rèn)為notic級別
trigger_error("用戶xxx想刪除ID為69的用戶名,已經(jīng)記錄到日志,請注意這個(gè)小子",E_USER_ERROR);

3.2 錯(cuò)誤日志記錄到操作系統(tǒng)日志中

先配置 php.ini 文件

    error_reporting = E_ALL     //將向PHP發(fā)送每個(gè)錯(cuò)誤
  * display_errors=Off          //不顯示錯(cuò)誤報(bào)告
  * log_errors=On               //決定日志語句記錄的位置
    log_errors_max_len=1024     //每個(gè)日志項(xiàng)的最大長度
  * error_log=syslog            //指定錯(cuò)誤寫進(jìn)的文件

使用四個(gè)函數(shù)來記錄日志:

//define_syslog_variables(); 為系統(tǒng)日志初始化配置
//openlog();                打開一個(gè)日志鏈接
//syslog();                 發(fā)送一條日志記錄
//closelog();               關(guān)閉日志鏈接

試驗(yàn):

aa();//不再顯示日志,而是記錄到系統(tǒng)日志中去了。

目前的開發(fā)已經(jīng)淘汰這種方式,4個(gè)函數(shù)必須同時(shí)使用,課后可自行試驗(yàn),代碼如下:

define_syslog_variables(); 
openlog("PHP5", LOG_PID , LOG_USER);
syslog(LOG_WARNING, "警告報(bào)告向syslog中發(fā)送的演示,警告時(shí)間: ".date("Y/m/d H:i:s"));
closelog();

如何查看 Window 系統(tǒng)日志。

計(jì)算機(jī)右鍵 ---> 管理(G) ---> 系統(tǒng)工具 ---> 事件查看器 ---> Windows 日志 ---> 應(yīng)用程序

第4章 自定義錯(cuò)誤處理

自定義錯(cuò)誤報(bào)告的處理方式,可以完全繞過標(biāo)準(zhǔn)的PHP錯(cuò)誤處理函數(shù),這樣就可以按自己定義的格式打印錯(cuò)誤報(bào)告,或改變錯(cuò)誤報(bào)告打印的位置。

說白了就是不使用系統(tǒng)的錯(cuò)誤提示,改為自己的。

set_error_handler() -- 設(shè)置用戶自定義錯(cuò)誤處理。

參數(shù):mixed set_error_handler ( callable $error_handler [, int $error_types = E_ALL | E_STRICT ] )

回調(diào)函數(shù):回來調(diào)取函數(shù)。

所謂的回調(diào)函數(shù):

function demo(){
    return "我才不要呢";
}

function demo2(){
    return "我也不要";
}
function result($suan){
    return $suan();
}
//將函數(shù)名demo1 函數(shù)名demo2 作為字符串參數(shù)傳遞給result函數(shù),那么可以自動(dòng)調(diào)用上面的函數(shù),我們就說demo1,demo2是result的回調(diào)函數(shù)
echo result('demo2');

案例:

//回調(diào)函數(shù)也需要參數(shù)接收,參考手冊
/*
errno
第一個(gè)參數(shù) errno,包含了錯(cuò)誤的級別,是一個(gè) integer。

errstr
第二個(gè)參數(shù) errstr,包含了錯(cuò)誤的信息,是一個(gè) string。

errfile
第三個(gè)參數(shù)是可選的,errfile, 包含了發(fā)生錯(cuò)誤的文件名,是一個(gè) string。

errline
第四個(gè)參數(shù)是一個(gè)可選項(xiàng), errline, 包含了錯(cuò)誤發(fā)生的行號,是一個(gè) integer。
*/
function callbackset($errno,$errstr,$errfile,$errline){
    echo "自定義錯(cuò)誤處理:錯(cuò)誤級別:{$errno},錯(cuò)誤信息是:{$errstr}.所在文件:{$errfile}的第{$errline}行";
}


set_error_handler("callbackset");//此處設(shè)置為報(bào)錯(cuò)的返回信息交給callbackset自行處理

echo $aa;

特別注意:E_ERROR、E_PARSE、E_CORE_ERROR、E_CORE_WARNING、E_COMPILE_ERROR、E_COMPILE_WARNING是不會有效果的,通常會用原始的方式顯示。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 簡介 PHP提供了錯(cuò)誤處理和日志記錄的功能. 這些函數(shù)允許你定義自己的錯(cuò)誤處理規(guī)則,以及修改錯(cuò)誤記錄的方式. 這樣...
    零一間閱讀 739評論 0 2
  • 文件加載 語法形式:include、include_once、require、require_once4 種語法都...
    THEyAnJ閱讀 664評論 0 1
  • PHP錯(cuò)誤簡介 PHP提供了錯(cuò)誤處理和日志記錄的功能. 這些函數(shù)允許你定義自己的錯(cuò)誤處理規(guī)則,以及修改錯(cuò)誤...
    四月不見閱讀 4,643評論 0 7
  • 前言:關(guān)于PHP的錯(cuò)誤和異常我準(zhǔn)備用四大塊來說明,內(nèi)容如下: 一、錯(cuò)誤與異常的 區(qū)別 異常一般指非語法和編譯上的錯(cuò)...
    peanut___閱讀 870評論 1 2
  • //禁用錯(cuò)誤報(bào)告 error_reporting(0); //報(bào)告運(yùn)行時(shí)錯(cuò)誤 error_reporting(E_...
    沁心軒墨閱讀 812評論 1 1

友情鏈接更多精彩內(nèi)容