當 SQL 參數數量不固定(如動態 WHERE 條件、批次 INSERT)時,需將陣列參數動態綁定至 mysqli_stmt::bind_param。由於 bind_param 需傳入實際變量引用而非值,需用變量變量技巧構建引用陣列。
private function bindVars($stmt, $params) {
if ($params != null) {
// 1. 建立型別字串:i=integer, d=double, s=string, b=blob
$types = '';
foreach ($params as $param) {
if (is_int($param)) $types .= 'i';
elseif (is_float($param)) $types .= 'd';
elseif (is_string($param)) $types .= 's';
else $types .= 'b';
}
// 2. 第一個元素為型別字串
$bind_names[] = $types;
// 3. 為每個參數建立變量變量引用
for ($i = 0; $i < count($params); $i++) {
$bind_name = 'bind' . $i; // 變量名:bind0, bind1...
$$bind_name = $params[$i]; // 變量變量賦值
$bind_names[] = &$$bind_name; // 存入引用
}
// 4. 動態呼叫 bind_param
call_user_func_array(array($stmt, 'bind_param'), $bind_names);
}
return $stmt;
}
$mysqli = new mysqli("localhost", "user", "pass", "db");
$sql = "SELECT * FROM users WHERE status = ? AND role IN (?, ?) AND created_at > ?";
$stmt = $mysqli->prepare($sql);
// 動態參數陣列
$params = array(1, 'admin', 'editor', '2023-01-01');
// 綁定並執行
$this->bindVars($stmt, $params);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
print_r($row);
}
| 步驟 | 程式碼 | 說明 |
|---|---|---|
| 型別推斷 | is_int/is_float/is_string |
mysqli 需預先知道每個參數型別 |
| 變量變量建立引用 | $$bind_name = ...; $bind_names[] = &$$bind_name |
bind_param 要求傳入變量引用,非值 |
| 動態呼叫 | call_user_func_array([$stmt, 'bind_param'], $bind_names) |
解包陣列為可變參數列表 |
mysqli_execute_query (內建支援陣列參數)$mysqli = new mysqli("localhost", "user", "pass", "db");
$params = [1, 'admin', 'editor', '2023-01-01'];
$result = $mysqli->execute_query("SELECT * FROM users WHERE status = ? AND role IN (?, ?) AND created_at > ?", $params);
foreach ($result as $row) print_r($row);
$pdo = new PDO("mysql:host=localhost;dbname=db;charset=utf8", "user", "pass");
$params = [1, 'admin', 'editor', '2023-01-01'];
$stmt = $pdo->prepare("SELECT * FROM users WHERE status = ? AND role IN (?, ?) AND created_at > ?");
$stmt->execute($params);
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) print_r($row);
此技巧展示了 PHP 變量變量與引用機制的進階應用,理解其原理有助於深入掌握 PHP 內部運作。