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

PHP + mysqli 預處理語句完整指南:防注入、效能提升與程式碼範例

     編輯:PHP 相關知識

PHP + mysqli 預處理語句完整指南

預處理語句是防禦 SQL 注入的黃金標準,同時透過查詢計劃重用提升效能。本文以 mysqli 面向物件 API 為例,詳細講解 prepare → bind_param → bind_result → execute → fetch 完整流程。

核心流程圖解

  1. 準備:$stmt = $mysqli->prepare($sql) —— SQL 含 ? 佔位符
  2. 綁定參數:$stmt->bind_param('types', $var1, ...) —— 類型字串:i(整數)/d(浮點)/s(字串)/b(blob)
  3. 綁定結果:$stmt->bind_result($col1, $col2, ...) —— 對應 SELECT 欄位順序
  4. 執行:$stmt->execute()
  5. 逐行取值:while ($stmt->fetch()) { ... }
  6. 釋放/關閉:$stmt->free_result(); $stmt->close();

完整程式碼範例:查詢 id > 5 的新聞

<?php
$mysqli = new MySQLi("localhost", "root", "123456", "liuyan");
if ($mysqli->connect_error) {
    die("連線失敗: " . $mysqli->connect_error);
}

$sql = "SELECT id, title, contents FROM news WHERE id > ?";
$stmt = $mysqli->prepare($sql);

$id = 5;                     // 只查 id > 5
$stmt->bind_param("i", $id); // i = integer

$stmt->bind_result($id, $title, $contents);
$stmt->execute();

while ($stmt->fetch()) {
    echo "--$id--$title--$contents--<hr>";
}

$stmt->free_result();
$stmt->close();
$mysqli->close();
?>

關鍵細節補充

細節說明
類型字串對應變數數量必須一致;bind_param('iss', $id, $name, $content)
參數傳址PHP 5.3+ 必須傳變數,不可直接傳常數:bind_param('i', 5) ❌ → $v=5; bind_param('i', $v) ✅
結果綁定順序嚴格對應 SELECT 列順序,欄位名不重要
多結果集預處理不支援 multi_query,需改用一般查詢
錯誤處理$stmt->error、$stmt->errno 取得最後錯誤

為什麼要用預處理?

  • 安全:資料與 SQL 結構分離,徹底杜絕注入
  • 效能:重複執行同結構 SQL 時,伺服器端重用解析樹
  • 可讀:參數化讓 SQL 模板更清晰

進階:封裝成通用查詢方法

function queryPrepared($mysqli, $sql, $types, $params, $columns) {
    $stmt = $mysqli->prepare($sql);
    if (!$stmt) return false;
    $stmt->bind_param($types, ...$params);
    $stmt->execute();
    $stmt->bind_result(...$columns);
    $results = [];
    while ($stmt->fetch()) {
        $row = [];
        foreach ($columns as $i => $col) $row[$col] = $$col;
        $results[] = $row;
    }
    $stmt->close();
    return $results;
}

// 使用
$rows = queryPrepared($mysqli,
    "SELECT id, title FROM news WHERE id > ? AND status = ?",
    "is", [$minId, 1],
    ['id', 'title']
);

掌握預處理是 PHP 後端進階的必修課。建議在專案中建立資料庫存取層(DAL)強制使用預處理,杜絕手寫拼接 SQL。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved