【问题标题】:PDO binding with bindValue not working与 bindValue 的 PDO 绑定不起作用
【发布时间】:2015-06-10 04:02:04
【问题描述】:

我第一次尝试在 MySQL 数据库中使用准备好的语句和 PDO。我一直在参考 MySQL 开发人员的 PDO 教程、关于 PHP 数据对象的 PHP 手册页以及 SO 中涵盖此问题的众多答案,但我无法找到我做错了什么。

具体来说,我无法使用命名占位符。有人可以帮我改正吗?

我使用的数据库表,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);

但是对于仍然给我用户 0 的记录的用户 2。我也尝试过使用 bindParam,但我认为在这种情况下我应该使用 bindValue。

我在查询后添加了 $stmt->debugDumpParams() 并显示:

SQL: [23] SELECT * FROM todo_list
Params:  0

我不知道 Params 0 是否有用。

我对绑定的使用失败了,但我不明白为什么。我在最新安装的 Ubuntu 上运行它。

【问题讨论】:

  • 你不能绑定到不存在的东西。您尚未准备好查询。你正在准备一个没有参数的查询,然后尝试绑定到没有参数的东西,然后执行一个查询,但没有先准备它......这永远不会工作。

标签: php mysql pdo


【解决方案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 . ')';
}

【讨论】:

  • 谢谢,在@Brad 发表评论后,我一直在努力解决序列问题,并尝试了其他方法,但你的工作完美无缺,并为我澄清了这一点。
猜你喜欢
  • 2013-01-03
  • 2011-02-11
  • 1970-01-01
  • 2013-03-08
  • 2016-01-28
  • 2014-06-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多