PDOStatement 提供三種綁定方法,分別用於「輸入參數綁定」與「輸出欄位綁定」,混淆使用會導致難以除錯的錯誤。
<?php
$stmt = $pdo->prepare('SELECT * FROM users WHERE name = :name');
$name = 'Alice';
// 正確:傳入變數參考
$stmt->bindParam(':name', $name);
// 錯誤:不能直接傳值
// $stmt->bindParam(':name', 'Alice'); // Fatal Error
// 執行時才取變數當前值
$name = 'Bob';
$stmt->execute(); // 實際查詢 Bob
特性:參考綁定、延遲取值、適合迴圈中重複執行同一語句且參數值變化。
<?php
$stmt = $pdo->prepare('SELECT * FROM users WHERE name = :name');
$name = 'Alice';
// 皆正確
$stmt->bindValue(':name', $name); // 變數
$stmt->bindValue(':name', 'Alice'); // 直接值
$stmt->bindValue(':name', $name, PDO::PARAM_STR); // 指定型別
特性:即時取值、可直接用常數、適合單次執行或固定參數。
<?php
$stmt = $pdo->query('SELECT name, email, age FROM users');
// 依欄位索引綁定
$stmt->bindColumn(1, $name);
$stmt->bindColumn(2, $email);
// 依欄位名稱綁定
$stmt->bindColumn('age', $age);
while ($stmt->fetch(PDO::FETCH_BOUND)) {
// 每次 fetch 會自動更新 $name, $email, $age
echo "$name | $email | $age\n";
}
特性:配合 PDO::FETCH_BOUND 使用、每次 fetch 更新變數、適合大量資料逐行處理避免建立陣列開銷。
| 場景 | 推薦方法 |
|---|---|
| 迴圈中重複執行,參數值每次不同 | bindParam |
| 單次執行、固定參數、或需直接傳常數 | bindValue |
| SELECT 查詢大量資料,逐行處理不想建立陣列 | bindColumn + FETCH_BOUND |
| 簡單查詢直接取得關聯陣列 | fetch(PDO::FETCH_ASSOC)(無需綁定) |
bindParam 第二參數必須是變數,不能是表達式或常數。bindColumn 僅對 fetch() 生效,fetchAll() 不會更新變數。PDO::PARAM_*)建議顯式指定,避免隱性轉型問題。