2015-04-05 73 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