PDO绑定参数(bindParam)和预处理语句(prepared statement)一起使用无效。

21

好的,这是问题:

以下代码可以正常工作:

$STH = $DBH->prepare("SELECT * FROM juegos WHERE id = 1");
$STH->execute();

这不行:

$STH = $DBH->prepare("SELECT * FROM juegos WHERE id = :id");
$STH->bindParam(':id', '1', PDO::PARAM_STR);
$STH->execute();

我到底做错了什么?它甚至没有抛出异常

谢谢大家!

另外,这就是整个代码

<?php
    try {
        $DBH = new PDO("everything is", "ok", "here");

        $DBH->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );

        $STH = $DBH->prepare("SELECT * FROM juegos WHERE id = :id");
        $STH->bindParam(':id', '1', PDO::PARAM_STR);
        $STH->execute();

        $STH->setFetchMode(PDO::FETCH_ASSOC);

        while($row = $STH->fetch()) {
            echo $row['nombre']."<br/>";
        }

        $DBH = null;

        echo "Todo salió bien";

    } catch (PDOException $e) {
        echo "Error";
    }

?>

我“能”或者我“不能”,因为这个也不起作用: $STH = $DBH->prepare("SELECT nombre FROM juegos WHERE id = :id"); $STH->bindParam(':id', 1, PDO::PARAM_INT); $STH->execute(); - arielnmz
您不能在表名上使用参数。抱歉,那是一个打字错误。 - juergen d
bindParam 的第二个参数必须是一个引用。你不能直接传递值 1。作为替代方案,请尝试使用 bindValue - sofl
5个回答

28

完美地做动态 WHEREs ;) - boctulus

7

PHP bindParam()将PHP变量绑定到与用于准备语句的SQL语句中的对应命名或问号占位符。

使用bindParam的正确方式是:

$id = 1;
$sth = $DBH->prepare("SELECT * FROM juegos WHERE id = :id");
$sth->bindParam(':id', $id, PDO::PARAM_INT);// use bindParam to bind the variable
                          // ^ PDO::PARAM_INT - the value of the variable $id should be an int
                     // ^ $id - the variable being represented by ':id',
              // ^ :id - represents the variable
              // $id - the variable being represented by ':id',

PHP中的bindValue()函数将一个值绑定到与SQL语句中对应的具名或问号占位符。

$id=10;
$name=roadkill;
$sth = $dbh->prepare('SELECT *
    FROM juegos
    WHERE id < :id AND name = :name');
$sth->bindValue(':id', $id, PDO::PARAM_INT);// use bindValue to bind the variable's value
$sth->bindValue(':name', $name, PDO::PARAM_STR);// use bindValue to bind the variable's value

这两种方法的关键区别在于,与PDOStatement::bindValue()不同,使用bindParam()时,变量被绑定为引用,并且只会在调用PDOStatement::execute()时进行评估。

2

:tabla参数的值将由PDO自动引用和转义。执行的查询将变为:

SELECT * FROM 'juegos'

这不是有效的SQL语句。


那么为什么这个也不起作用呢? $STH = $DBH->prepare("SELECT nombre FROM juegos WHERE id = :id"); $STH->bindParam(':id', 1, PDO::PARAM_INT); $STH->execute(); - arielnmz
1
@arielnmz 因为你没有打开错误报告,而这是你应该做的。 - Your Common Sense
“错误报告”与准备语句中命名参数的绑定有什么关系? - arielnmz
1
@arielnmz 它会执行错误报告,并向您报告错误。 - Your Common Sense
@arielnmz 是的,如果你打开了错误报告并谷歌错误文本,这个问题确实很简单。 - Your Common Sense
显示剩余2条评论

1
不要直接将值传递给BindParam。
try {
       // $DBH = new PDO("everything is", "ok", "here");
        $DBH = new PDO("mysql:host=localhost;dbname=test", 'root', '');
        $DBH->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
        $STH = $DBH->prepare("SELECT * FROM statstracker WHERE SrNo = :id");
        $id = 1; // here you should keep it as variable and pass it to param
        $STH->bindParam(':id', $id, PDO::PARAM_STR);
        $STH->execute();

        $STH->setFetchMode(PDO::FETCH_ASSOC);

        while($row = $STH->fetch()) {
            echo $row['SrNo']."<br/>";
        }

        $DBH = null;

        echo "Todo salió bien";

    } catch (PDOException $e) {
        echo "Error";
    }

这个问题已经有了答案,不需要再添加任何内容。 - Your Common Sense
哦,但是这个人没有标记他的问题为已回答,我认为你给我的-1是因为注意到了这一点,你可以看到这个问题还没有被回答。当然,在网络上有很多类似的问题,我的答案对于这个问题来说是确切的。 - SAR
抱歉回复晚了(我不太习惯在'13年使用这个网站)。正确的答案是:1. 我不能使用预处理语句来定义表或列名,2. 如果我将引用作为参数,则必须使用 bindParam,如果我使用表达式结果的直接常量,例如 $var."foo",则必须使用 bindValue。但这是一个解决方法,也很有用。 - arielnmz

0

对我来说,将双引号替换为单引号解决了这个问题。

之前:

$STH = $DBH->prepare("SELECT * FROM statstracker WHERE SrNo = :id");

解决方案:

$STH = $DBH->prepare('SELECT * FROM statstracker WHERE SrNo = :id');

它可以工作,虽然不确定为什么。

希望能有所帮助!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接