2015-04-05 151 views
0

我想用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安裝。

+2

您不能綁定到不存在的東西。您尚未準備好查詢。你正在準備一個沒有參數的查詢,然後嘗試綁定到沒有參數的東西,然後執行一個查詢,但沒有先準備好......這將永遠不會工作。 – Brad 2015-04-05 16:53:57

回答

1

我想你已經把它倒過來了。使用綁定參數的正確方法應該是這樣的:

if ($tableName=="t_list") { 
    try { 
     $stmt = $db->prepare("SELECT * FROM t_list WHERE user_id=:user_id and list_name=:list_name"); 
     $stmt->bindValue(":user_id", $user_id, PDO::PARAM_INT); 
     $stmt->bindValue(":list_name", $list_name, PDO::PARAM_STR); 
     $stmt->execute(); 
     $rows = $stmt->fetchAll(); 
     foreach($rows 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 . ')'; 
} 
+0

謝謝,我在序列上掙扎,在@布拉德的評論後嘗試了其他人,但你的工作完美併爲我澄清了它。 – 2015-04-05 17:14:51