當前位置: 首頁> 最新文章列表> 如何封裝next_result() 和多結果處理為通用函數

如何封裝next_result() 和多結果處理為通用函數

gitbox 2025-05-02

在實際開發過程中,尤其是在使用MySQL 多查詢(multi-query)功能時,經常會遇到需要處理多個結果集的情況。如果沒有統一的處理方式,每次都手動調用next_result()store_result() ,不僅麻煩,還容易出錯。
為了讓代碼更加優雅、健壯,我們可以封裝一個通用函數,自動處理所有的結果集。下面我將一步步帶你了解怎麼做。

理解next_result()和多結果集的處理

在使用mysqli進行多查詢時(即一次性發送多條SQL 語句),每條語句對應一個結果集。使用next_result()可以讓mysqli對象移動到下一個結果集,而store_result()則負責提取當前結果集的數據。

如果不正確地處理這些結果集,很容易導致連接異常,或下一次查詢失敗。因此,完整地清理所有結果集非常重要

封裝一個通用的多結果處理函數

下面是一個示例,演示如何封裝一個處理所有結果集的函數,並且返回所有數據的數組:

 <?php

/**
 * 執行多查詢並處理所有結果集
 *
 * @param mysqli $mysqli MySQLi連接對象
 * @param string $multiQuery 要執行的多條SQL查詢語句(用分號隔開)
 * @return array 返回一個包含所有結果集數據的數組
 */
function executeMultiQuery(mysqli $mysqli, string $multiQuery): array
{
    $allResults = [];

    if ($mysqli->multi_query($multiQuery)) {
        do {
            if ($result = $mysqli->store_result()) {
                $data = [];
                while ($row = $result->fetch_assoc()) {
                    $data[] = $row;
                }
                $allResults[] = $data;
                $result->free();
            } else {
                // 當前結果可能是無結果集的,比如UPDATE或INSERT
                if ($mysqli->errno) {
                    throw new Exception("MySQL錯誤:" . $mysqli->error);
                }
                $allResults[] = null;
            }
        } while ($mysqli->more_results() && $mysqli->next_result());
    } else {
        throw new Exception("執行多查詢失敗:" . $mysqli->error);
    }

    return $allResults;
}

// 示例用法
$mysqli = new mysqli('localhost', 'root', 'password', 'testdb');

if ($mysqli->connect_errno) {
    die("連接失敗:" . $mysqli->connect_error);
}

try {
    $sql = "
        SELECT * FROM users;
        SELECT * FROM orders;
        UPDATE products SET stock = stock - 1 WHERE id = 5;
    ";
    $results = executeMultiQuery($mysqli, $sql);

    // 輸出所有查詢結果
    foreach ($results as $index => $resultSet) {
        echo "1。 " . ($index + 1) . " 個結果集:<br>";
        if (is_array($resultSet)) {
            foreach ($resultSet as $row) {
                echo htmlspecialchars(json_encode($row)) . "<br>";
            }
        } else {
            echo "(無返回結果,例如UPDATE或INSERT語句)<br>";
        }
        echo "<hr>";
    }
} catch (Exception $e) {
    echo "发生錯誤:" . $e->getMessage();
}

$mysqli->close();
?>

注意事項

  1. 及時釋放結果集資源:調用$result->free()非常重要,避免內存洩漏。

  2. 錯誤檢測:如果multi_query()或某一輪store_result()出錯,應及時捕獲異常,避免後續操作繼續出錯。

  3. 適配無結果集的操作UPDATEINSERTDELETE等語句沒有返回結果集,處理時需要做特殊判斷。

結語

通過封裝處理多結果集,我們不僅讓代碼更加簡潔,還能有效避免MySQL 連接混亂的問題。如果你的項目中需要頻繁處理多條SQL 查詢,強烈建議使用類似的方法進行標準化封裝。

如果你想了解更多關於多查詢的進階使用,比如事務(transaction)結合多查詢,或者如何在大項目中集成這樣的封裝,可以繼續關注我們的網站: https://gitbox.net ! ??