首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 自定義錯誤處理器:捕獲警告、記錄日誌與簡訊告警實戰代碼

     編輯:PHP 綜合知識

核心需求

生產環境需區分錯誤等級:致命錯誤立即告警、警告記錄日誌、解析錯誤自動提取問題 XML 片段並建立過濾字典,防止相同錯誤重複觸發。

完整實作代碼

<?php
error_reporting(E_ERROR | E_WARNING | E_PARSE);
set_error_handler('displayErrorHandler');

echo "time: " . date("Y-m-d H:i:s") . "\n";

function displayErrorHandler($errno, $errstr, $errfile, $errline) {
    $errMap = [
        E_ERROR => 'ERROR', E_WARNING => 'WARNING', E_PARSE => 'PARSE',
        E_NOTICE => 'NOTICE', E_CORE_ERROR => 'CORE_ERROR',
        E_CORE_WARNING => 'CORE_WARNING', E_COMPILE_ERROR => 'COMPILE_ERROR',
        E_COMPILE_WARNING => 'COMPILE_WARNING', E_USER_ERROR => 'USER_ERROR',
        E_USER_WARNING => 'USER_WARNING', E_USER_NOTICE => 'USER_NOTICE',
        E_ALL => 'ALL', E_STRICT => 'STRICT'
    ];
    $level = $errMap[$errno] ?? 'UNKNOWN';
    $msg = sprintf("%s: %s at %s(%d)", $level, $errstr, $errfile, $errline);

    if (in_array($errno, [E_ERROR, E_WARNING, E_PARSE], true)) {
        echo $msg . "\n"; // 控制台輸出

        // 致命錯誤/警告發送簡訊
        if (in_array($errno, [E_ERROR, E_WARNING], true)) {
            sendBankMsg($errstr);
        }

        // XML 解析錯誤自動提取問題片段
        if (strpos($errstr, 'xml_parse(): Bytes:') !== false) {
            writeFilterFile($errstr);
        }
    }
}

// 16進位轉二進位
function hex2bin($hex) {
    $bin = '';
    for ($i = 0; $i < strlen($hex); $i += 2) {
        $bin .= chr(hexdec(substr($hex, $i, 2)));
    }
    return $bin;
}

// 寫入過濾字典
function writeFilterFile($errstr) {
    if (strpos($errstr, 'xml_parse(): Bytes:') === false || strpos($errstr, ' 0x') === false) return;

    $file = 'filtetext.php';
    if (file_exists($file)) include $file; // 載入現有陣列

    $clean = str_replace(['xml_parse(): Bytes:', ' 0x'], '', $errstr);
    $bin = hex2bin($clean);
    $filtetextArr[] = $bin;
    $filtetextArr = array_unique($filtetextArr);

    $code = "<?php\n\$filtetextArr = array('" . implode("','", $filtetextArr) . "');\n?>";
    fileWrite($file, $code);
}

// 簡訊發送(Socket POST)
function sendBankMsg($msg) {
    $params = http_build_query(['msg' => $msg, 'posttime' => time()]);
    $fp = fsockopen('www.admin.com', 80);
    if (!$fp) return;

    $header = "POST /action/bank/bankmsg.php HTTP/1.1\r\n";
    $header .= "Host: www.admin.com\r\n";
    $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
    $header .= "Content-Length: " . strlen($params) . "\r\n";
    $header .= "Connection: Close\r\n\r\n";
    $header .= $params . "\r\n";

    fwrite($fp, $header);
    fclose($fp);
}

// 安全寫檔(檔案鎖 + 忽略用戶中斷)
function fileWrite($file, $content, $mode = 'w') {
    ignore_user_abort(true);
    $fp = fopen($file, $mode);
    if (flock($fp, LOCK_EX)) {
        fwrite($fp, $content);
        flock($fp, LOCK_UN);
    }
    fclose($fp);
    ignore_user_abort(false);
}

關鍵設計亮點

  1. 分級處理:ERROR/WARNING 觸發簡訊,PARSE 僅記錄
  2. XML 錯誤自動學習:提取 16 進位位元組片段 → 轉二進位 → 寫入 PHP 陣列檔,下次遇相同字元直接過濾
  3. 檔案鎖保護:flock(LOCK_EX) 防併發寫入損壞字典
  4. Socket 直連:不依賴 PHP mail(),可控性更強
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved