當前位置: 首頁> 最新文章列表> 如何封裝stmt_init 為通用數據庫操作類

如何封裝stmt_init 為通用數據庫操作類

M66 2025-05-17

在PHP開發中,數據庫操作是必不可少的部分,常見的操作包括增、刪、改、查等。然而,傳統的數據庫交互方式常常會存在代碼冗餘、SQL注入漏洞、性能瓶頸等問題。為了提升數據庫交互效率、增強代碼可複用性,我們可以使用mysqli::stmt_init方法封裝一個通用的數據庫操作類。通過這種方式,不僅可以提高效率,還能防止SQL注入漏洞。

在本文中,我們將詳細介紹如何使用mysqli::stmt_init函數來創建一個通用的數據庫操作類,並且通過合理的封裝使得數據庫交互更加高效和安全。

1. 什麼是mysqli::stmt_init函數?

mysqli::stmt_init是MySQLi 擴展中的一個方法,用於初始化一個mysqli_stmt對象。 mysqli_stmt對象代表了一條準備好的SQL 語句,它在執行SQL 查詢時比傳統的查詢方式更加高效,特別是當需要執行多次類似的SQL 查詢時。通過預處理語句,可以減少SQL 解析的時間,提高執行效率。

2. 使用mysqli::stmt_init的優勢

  • 性能提升:通過預處理語句,MySQL 會對SQL 查詢進行一次編譯和優化,而不需要每次都進行解析。

  • 防止SQL 注入:通過綁定參數,避免了直接插入用戶輸入數據,從而有效防止SQL 注入攻擊。

  • 代碼復用性:封裝數據庫操作類後,可以在不同的地方重複使用,提高代碼的複用性。

3. 封裝通用的數據庫操作類

首先,我們需要創建一個數據庫連接類,並在該類中使用mysqli::stmt_init進行SQL 操作的封裝。

3.1 數據庫連接類

class Database {
    private $mysqli;
    
    public function __construct($host, $username, $password, $dbname) {
        // 創建數據庫連接
        $this->mysqli = new mysqli($host, $username, $password, $dbname);
        
        // 檢查連接
        if ($this->mysqli->connect_error) {
            die("Connection failed: " . $this->mysqli->connect_error);
        }
    }

    // 準備 SQL 語句並執行
    public function executeQuery($sql, $params = []) {
        // 初始化語句
        $stmt = $this->mysqli->stmt_init();
        
        // 準備 SQL 語句
        if (!$stmt->prepare($sql)) {
            die("Error in preparing statement: " . $stmt->error);
        }

        // 綁定參數
        if (!empty($params)) {
            // 獲取參數類型
            $types = str_repeat('s', count($params));  // 假設所有參數都是字符串類型
            $stmt->bind_param($types, ...$params);
        }

        // 執行查詢
        if ($stmt->execute()) {
            // 返回結果集
            return $stmt->get_result();
        } else {
            die("Error in executing statement: " . $stmt->error);
        }
    }

    // 關閉數據庫連接
    public function close() {
        $this->mysqli->close();
    }
}

3.2 使用該類進行數據庫操作

在上述代碼中,我們封裝了一個數據庫操作類Database ,該類可以執行任何SQL 查詢。使用時,我們只需要傳入SQL 語句和參數即可。

例如,插入一條數據:

 $db = new Database('localhost', 'root', 'password', 'm66.net');

// 插入數據
$sql = "INSERT INTO users (name, email) VALUES (?, ?)";
$params = ['John Doe', 'johndoe@m66.net'];
$db->executeQuery($sql, $params);

查詢數據:

 $sql = "SELECT * FROM users WHERE email = ?";
$params = ['johndoe@m66.net'];
$result = $db->executeQuery($sql, $params);

// 輸出結果
while ($row = $result->fetch_assoc()) {
    echo "Name: " . $row['name'] . ", Email: " . $row['email'] . "<br>";
}

$db->close();

3.3 擴展功能:批量操作

除了執行單條SQL 查詢,封裝的數據庫操作類還可以支持批量操作。通過在類中添加一個批量操作的方法,我們可以高效地進行多個數據操作。

 public function executeBatchQuery($sql, $paramsList) {
    // 初始化語句
    $stmt = $this->mysqli->stmt_init();
    
    // 準備 SQL 語句
    if (!$stmt->prepare($sql)) {
        die("Error in preparing statement: " . $stmt->error);
    }

    // 獲取參數類型
    $types = str_repeat('s', count($paramsList[0])); // 假設所有參數都是字符串類型
    
    // 遍歷參數列表並執行
    foreach ($paramsList as $params) {
        $stmt->bind_param($types, ...$params);
        $stmt->execute();
    }
    
    return true;
}

批量插入數據:

 $sql = "INSERT INTO users (name, email) VALUES (?, ?)";
$paramsList = [
    ['Alice', 'alice@m66.net'],
    ['Bob', 'bob@m66.net'],
    ['Charlie', 'charlie@m66.net']
];
$db->executeBatchQuery($sql, $paramsList);

4. 總結

通過使用mysqli::stmt_init函數,我們可以輕鬆封裝一個高效、安全的數據庫操作類,避免了重複代碼的編寫,並提升了性能。通過預處理語句,我們能夠防止SQL 注入,提高應用程序的安全性。封裝後的數據庫操作類不僅可以執行單條查詢,還能支持批量操作,進一步提高效率。