我想用MySQL數據庫第一次使用準備好的語句和PDO。我一直指的是MySQL開發人員的PDO教程,PHP數據對象的PHP手冊頁以及涵蓋這個的衆多答案,但是我一直無法找到我做錯了什麼。PDO與bindValue綁定不起作用
具體而言,我無法獲得命名佔位符的工作。有人能幫我解決嗎?
我正在使用的數據庫表,t_list是
`user_id` mediumint(8) unsigned NOT NULL,
`list_name` char(30) NOT NULL,
`list_items` longtext NOT NULL,
`timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`user_id`,`list_name`)
不安全的做法,直接在SQL中使用的變量,工程...
if ($tableName=="t_list") {
try {
$stmt = $db->prepare("SELECT * FROM t_list");
$stmt->bindValue(":user_id", $user_id, PDO::PARAM_INT);
$stmt->bindValue(":list_name", $list_name, PDO::PARAM_STR);
$stmt->execute();
foreach($db->query("SELECT `list_items` FROM t_list WHERE user_id=$user_id AND list_name='$list_name'") as $row) {
$found = 1;
echo $row['list_items'];
}
$stmt->debugDumpParams();
} catch(PDOException $e) {
echo "An error occured reading 't_list' table!";
echo $e->getMessage();
}
if ($found==0) {
echo "read failed : " . $user_id . "/" . $list_name . " not found:";
}
} else {
echo 'tableName not recognized (' . $tableName . ')';
}
...但我的想法我應該能夠做的代碼安全是:
foreach($db->query("SELECT `list_items` FROM t_list WHERE user_id=:user_id AND list_name=:list_name") as $row) {
正如在另一個SO答案建議,我這樣做第一:
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
沒有MySQL或PHP錯誤消息。
會發生什麼:
說在$ user_id的值是2和$ LIST_NAME是 「AAAA」 到達上面的代碼時。表中有一條與用戶2 /列表AAAA相對應的記錄,但不是檢索那條記錄,而是檢索用戶0的所有記錄。如果將user_id替換爲$ user_id,它將恢復正確的用戶,但所有數據爲該用戶,而不僅僅是一個list_name記錄。
我試圖
$stmt->bindValue(":user_id", (int) trim ($user_id), PDO::PARAM_INT);
但對於用戶2仍然給我的用戶0的記錄。我也嘗試bindParam,但我認爲bindValue是我應該在這種情況下使用。
我查詢後添加$ stmt-> debugDumpParams(),它表明:
SQL: [23] SELECT * FROM todo_list
Params: 0
我不知道PARAMS 0是一個有用的指標。
我使用綁定失敗,但我不明白爲什麼。我正在使用最新的Ubuntu安裝。
您不能綁定到不存在的東西。您尚未準備好查詢。你正在準備一個沒有參數的查詢,然後嘗試綁定到沒有參數的東西,然後執行一個查詢,但沒有先準備好......這將永遠不會工作。 – Brad 2015-04-05 16:53:57