1. 程式人生 > 實用技巧 >PHP 錯誤處理及除錯

PHP 錯誤處理及除錯

錯誤處理及除錯

  • 常見錯誤型別

    • 語法錯誤
    • 執行錯誤
    • 邏輯錯誤
    • 環境錯誤
  • 錯誤級別

    • notice 提示,報錯後繼續執行
    • warning 警告,報錯後繼續執行
    • error 致命錯誤,報錯後停止執行

如何處理錯誤

  • 顯示錯誤報告
    • 修改配置檔案(php.ini),實現顯示錯誤報告
      • error_reporting = E_ALL 報告所有的錯誤
      • display_errors = On 將錯誤顯示在瀏覽器上
    • error_reporting()ini_set(),ini配置僅指令碼中生效
    • die() 函式,自定義輸出錯誤資訊,常用於業務邏輯錯誤提示
# error_reporting()函式 和 ini_set()函式
<?php
    ini_set('display_errors', 1);
    $rand_num= rand(0, 1);
    echo $rand_num;
    if($rand_num==0){
        # 報告所有錯誤
        error_reporting(E_ALL);
    }else{
        # 報告除了Notice之外的所有錯誤
        error_reporting(E_ALL & ~E_NOTICE);
    }
    echo $info;
?>
# die()函式,自定義輸出錯誤資訊
<?php
    header('Content-Type: text/html;charset=utf-8');
    $result= defined('PAI');
    if(!$result){
        die("PAI常量不存在!");
    }
?>
# 通過邏輯運算子的短路特性,die()與or配合使用
<?php
    $result= defined('PAI') or die("PAI常量不存在!");
?>
  • 記錄錯誤日誌
    • 修改配置檔案(php.ini),實現顯示錯誤報告
      • error_reporting = E_ALL
        報告所有的錯誤
      • log_error=On; 將錯誤記錄在日誌中
      • error_log=/tmp/php_errors.log 錯誤日誌儲存的地址
    • error_log() 函式,將錯誤記錄到指定的日誌檔案中或傳送電子郵件到指定地址
      • 0 預設。根據在 php.ini 檔案中的 error_log 配置,錯誤被髮送到伺服器日誌系統或檔案。
      • 1 錯誤被髮送到 destination 引數中的地址。只有該型別使用 headers 引數。
      • 3 錯誤傳送到檔案目標字串。
<?php
    $a= 12;
    if($a<10){
        error_log("$a小於10", 0);
        echo "here";
    }elseif($a==10){
        error_log("$a等於10", 1, "[email protected]");
    }elseif($a>10){
        error_log("$a大於10", 3, "G:/error.log");
    }
?>

開發過程中的模式

  • 開發過程中的模式
    • 開發模式:錯誤顯示在瀏覽器上,不要記錄在日誌中
    • 執行模式:錯誤不顯示在瀏覽器上,記錄是日誌中
<?php
  $debug=false;		//true:開發模式  false:執行模式
  ini_set('error_reporting',E_ALL);	//所有的錯誤有報告
  if($debug){
    ini_set('display_errors','on');	//錯誤顯示是瀏覽器上
    ini_set('log_errors','off');	//錯誤不顯示在日誌中
  }else{
    ini_set('display_errors','off');
    ini_set('log_errors','on');
    ini_set('error_log','./err.log');	//錯誤日誌儲存的地址
  }
  echo $num;    //測試
?>

自定義錯誤處理

  • trigger_error 函式
    • 產生一個使用者級別的error/warning/notice資訊
    • 使用者級別的錯誤的常量名中一定要帶有USER
<?php
  $age=100;
  if($age>80){
    # 預設觸發了notice級別的錯誤
    trigger_error('年齡不能超過80歲');  
    # 觸發notice級別的錯誤
    trigger_error('年齡不能超過80歲',E_USER_NOTICE);	
    # 觸發warning級別的錯誤
    trigger_error('年齡不能超過80歲',E_USER_WARNING);
    # 觸發error級別的錯誤
    trigger_error('年齡不能超過80歲', E_USER_ERROR);   
  }
?>
  • set_error_handler() 函式
    • 自定義錯誤處理器
<?php
    function error() {
        echo '這是自定義錯誤處理';
    }
    # 註冊錯誤處理函式,只要有錯誤就會自動的呼叫錯誤處理函式
    set_error_handler('error');	
    echo $num;
?>
# 帶引數
<?php
  /**
    * 自定義錯誤處理函式
    * @param $errno int 錯誤類別
    * @param $errstr string 錯誤資訊
    * @param $errfile string 檔案地址
    * @param $errline int 錯誤行號
  **/
  function error($errno,$errstr,$errfile,$errline) {
    switch($errno){
      case E_NOTICE:
      case E_USER_NOTICE:
        echo '記錄在日誌中,上班後在處理<br>';
        break;
      case E_WARNING:
      case E_USER_WARNING:	
        echo '給管理員發郵件<br>';
        break;
      case E_ERROR:
      case E_USER_ERROR:
        echo '給管理員打電話<br>';
        break;
      }
      echo "錯誤資訊:{$errstr}<br>";
      echo "錯誤檔案:{$errfile}<br>";
      echo "錯誤行號:{$errline}<br>";
  }
  set_error_handler('error');
  echo $num;
?>

異常處理

  • 異常的處理
    • throw 關鍵字丟擲異常
    • try{} catch(){} 捕獲異常
<?php
    function checkNum($num){
        if($num > 1){
            # 丟擲自定義異常
            throw new Exception("Value must be 1 or below");
        }
        return true;
    }
    # 可能觸發異常的程式碼
    try{
        checkNum(2);
    }
    # 捕獲異常
    catch(Exception $e){
        echo 'message:'.$e-> getMessage();
    }
?>
  • 頂層異常處理器
    • 用於沒有用try/catch塊來捕獲的異常
<?php
    function ExceptionHandle($exception){
        echo "<b>異常資訊:</b>".$exception-> getMessage();
    }
    set_exception_handler("ExceptionHandle");
    throw new Exception("你沒有捕獲的異常來了");
?>

PHP除錯技術

  • 使用輸出函式進行除錯

    • print() 用於輸出字串
    • echo() 用於輸出一個或多個字串
    • print_r() 用於列印一個變數易於理解的資訊,如陣列
    • var_dump() 用於列印變數的相關資訊,如布林值
  • 使用檔案記錄進行除錯

    • file_put_contents() 可以將程式的相關資訊記錄到某個檔案中
<?php
  date_default_timezone_set("Asia/Shanghai");
  $path= $_SERVER['DOCUMENT_ROOT']."/error_log.txt";
  $data= 10;
  if($data> 5){
    # 將除錯資訊追加記錄到檔案error_log.txt中
    file_put_contents($path, date("Y-m-d H:i:s", time())."資料大於5\r\n", FILE_APPEND);
  }
?>
  • Xdebug除錯
# php.ini 中追加配置
[Xdebug]
zend_extension=D:\Program Files\xampp\php\ext\php_xdebug.dll
xdebug.profiler_enable=on
xdebug.remote_enable=on
xdebug.remote_handler=dbgp
xdebug.remote_host=localhost
xdebug.remote_port=9000
xdebug.idekey=Visual Studio Code
xdebug.trace_output_dir="../Projects/xdebug"
xdebug.profiler_output_dir="../Projects/xdebug"
# 測試程式
<?php
	textXdebug();
	function textXdebug(){
		requireFile();
	}
	function requireFile(){
		require_once('abc.php');
	}
?>