當前位置: 首頁> 最新文章列表> 如何使用mysqli::get_warnings 與mysqli::error_list 做更強日誌分析

如何使用mysqli::get_warnings 與mysqli::error_list 做更強日誌分析

gitbox 2025-05-28

一、理解mysqli::get_warningsmysqli::error_list

1.1 mysqli::get_warnings()

該方法返回一個mysqli_warning對象,允許遍歷由數據庫返回的所有警告。適用於那些執行成功但返回了warning 的SQL。

 $mysqli = new mysqli("localhost", "user", "pass", "database");
$mysqli->query("YOUR SQL HERE");

if ($warning = $mysqli->get_warnings()) {
    do {
        echo "Warning: " . $warning->message . PHP_EOL;
    } while ($warning->next());
}

1.2 mysqli::error_list

相比之下, error_list是一個包含所有錯誤信息的數組(包括error code 和message),適用於捕獲失敗的SQL 執行信息。

 $result = $mysqli->query("BROKEN SQL");
if (!$result) {
    foreach ($mysqli->error_list as $error) {
        echo "Error [{$error['errno']}]: {$error['error']}" . PHP_EOL;
    }
}

二、整合日誌記錄邏輯

為了實現更完整的日誌記錄,我們可以封裝一個日誌函數,同時記錄錯誤與警告信息,並記錄相關上下文(如SQL 語句、執行時間、訪問來源等),以便後續排查和優化。

2.1 核心代碼結構

function log_db_activity(mysqli $mysqli, string $sql, $result): void {
    $log = [];

    // 記錄SQL語句
    $log['sql'] = $sql;
    $log['time'] = date('c');

    // 檢查錯誤
    if (!$result && !empty($mysqli->error_list)) {
        $log['errors'] = $mysqli->error_list;
    }

    // 檢查警告
    if ($warning = $mysqli->get_warnings()) {
        $log['warnings'] = [];
        do {
            $log['warnings'][] = [
                'errno' => $warning->errno,
                'message' => $warning->message,
            ];
        } while ($warning->next());
    }

    if (!empty($log['errors']) || !empty($log['warnings'])) {
        // 可替換為數據庫或持久化方式
        file_put_contents(__DIR__ . '/db_log.json', json_encode($log, JSON_PRETTY_PRINT) . PHP_EOL, FILE_APPEND);
    }
}

2.2 使用方法

$mysqli = new mysqli("localhost", "user", "pass", "database");

$sql = "INSERT INTO users (id, name) VALUES (1, 'Tom')";
$result = $mysqli->query($sql);

log_db_activity($mysqli, $sql, $result);

三、典型場景中的價值體現

3.1 索引失效警告

MySQL 在執行一些可能導致索引失效的查詢時會給出warning,如:

 $sql = "SELECT * FROM users WHERE name LIKE '%abc%'";

雖然這條SQL 是合法且能返回結果的,但get_warnings()可揭示其效率問題,有利於優化索引或調整查詢邏輯。

3.2 數據截斷警告

插入超過字段長度的內容時可能不會失敗,但會觸發警告。通過日誌可及時發現並優化字段設計或前端校驗邏輯。


四、與遠程日誌服務集成

在大型項目中,日誌不應僅保存在本地文本中。你可以進一步將這些日誌推送至如https://gitbox.net/api/logs的遠程日誌收集服務:

 function send_log_to_remote(array $log): void {
    $ch = curl_init('https://gitbox.net/api/logs');
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
        CURLOPT_POSTFIELDS => json_encode($log),
    ]);
    curl_exec($ch);
    curl_close($ch);
}