經常使用模塊之PHP錯誤處理

第1章 錯誤報告級別

PHP 程序的錯誤通常歸屬於下列三個領域:php

語法錯誤:安全

​ 語法錯誤最多見,而且也容易修復。如:代碼中遺漏一個分號。這類錯誤會阻止腳本的執行。 服務器

運行時錯誤:框架

​ 這種錯誤通常不會阻止PHP腳本的執行,但會阻止當前要作的事情。輸出一條錯誤,但php腳本繼續執行。函數

邏輯錯誤:工具

​ 這種錯誤最麻煩,既不阻止腳本執行,也不輸出錯誤消息。編碼

圖解 Apache Web 服務器與 PHP 引擎的關係。操作系統

案例:.net

//語法錯誤,忘記加分號
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是不會有效果的,一般會用原始的方式顯示。

相關文章
相關標籤/搜索