在 PHP 開發中,資料庫操作的安全性至關重要。mysqli 擴展庫提供的預處理語句(Prepared Statements)是防止 SQL 注入攻擊的核心機制。預處理語句將 SQL 邏輯與資料分離,先讓資料庫編譯 SQL 模板,再綁定參數執行,從根本上杜絕了惡意 SQL 代碼注入的風險。
以下範例展示如何使用預處理語句高效插入多筆資料:
<?php
// 1. 建立資料庫連線
$mysqli = new MySQLi("localhost", "root", "root", "test");
if ($mysqli->connect_error) {
die("連線失敗: " . $mysqli->connect_error);
}
// 2. 準備 SQL 模板(使用 ? 佔位符)
$sql = "INSERT INTO user1 (name, password, email, age) VALUES (?, ?, ?, ?)";
$stmt = $mysqli->prepare($sql);
// 3. 綁定參數類型:s=字串, i=整數
$stmt->bind_param("sssi", $name, $password, $email, $age);
// 4. 批次執行插入
$users = [
["小芳", "123456", "xiaofang@126.com", 18],
["小楊", "123456", "xiaoyang@126.com", 18],
["小G", "123456", "xiaoG@126.com", 18]
];
foreach ($users as $user) {
[$name, $password, $email, $age] = $user;
$stmt->execute();
}
if ($stmt->error) {
echo "操作失敗: " . $stmt->error;
} else {
echo "成功新增 " . $stmt->affected_rows . " 筆資料";
}
// 5. 釋放資源
$stmt->close();
$mysqli->close();
?>
預處理語句同樣適用於 SELECT 查詢,配合 bind_result() 可直接將查詢結果映射到變數:
<?php
$mysqli = new MySQLi("localhost", "root", "root", "test");
if ($mysqli->connect_error) {
die("連線失敗: " . $mysqli->connect_error);
}
// 查詢 ID 大於 5 的用戶
$sql = "SELECT id, name, email FROM user1 WHERE id > ?";
$stmt = $mysqli->prepare($sql);
$id = 5;
$stmt->bind_param("i", $id); // 綁定查詢條件
$stmt->bind_result($id, $name, $email); // 綁定結果欄位
$stmt->execute();
// 逐行獲取結果
while ($stmt->fetch()) {
echo "
{$id}--{$name}--{$email}";
}
// 釋放資源
$stmt->free_result();
$stmt->close();
$mysqli->close();
?>
| 錯誤類型 | 錯誤做法 | 正確做法 |
|---|---|---|
| 類型不匹配 | bind_param("i", $stringVar) | 確保類型標識與變數類型一致 |
| 未檢查錯誤 | 直接執行 execute() | 執行後檢查 $stmt->error |
| 資源洩漏 | 未關閉 statement | 務必呼叫 close() 釋放資源 |
| 重複 prepare | 迴圈中重複 prepare() | 迴圈外 prepare,迴圈內 bind/execute |
實際開發中常需根據用戶輸入動態建構查詢條件:
function buildUserQuery($mysqli, $filters) {
$conditions = [];
$params = [];
$types = "";
if (!empty($filters['name'])) {
$conditions[] = "name LIKE ?";
$params[] = "%{$filters['name']}%";
$types .= "s";
}
if (!empty($filters['min_age'])) {
$conditions[] = "age >= ?";
$params[] = $filters['min_age'];
$types .= "i";
}
$sql = "SELECT * FROM user1";
if ($conditions) {
$sql .= " WHERE " . implode(" AND ", $conditions);
}
$stmt = $mysqli->prepare($sql);
if ($params) {
$stmt->bind_param($types, ...$params); // PHP 5.6+ 支援參數解包
}
$stmt->execute();
return $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
}
mysqli 預處理語句是 PHP 開發者必須掌握的核心技能。它不僅提供了企業級的安全防護,更能提升高併發場景下的資料庫性能。記住三個核心原則:永不拼接 SQL 字串、嚴格綁定參數類型、及時釋放資源。