PDOStatement::bindParam 第一次调用后不起作用

PDOStatement::bindParam doesn't work after the first call

我在编写使用 PDO 连接到数据库的简单 class 时遇到一点问题。
问题是 PDOStatement::bindParam 在循环中的第一次调用后不起作用,我的意思是如果我有两个参数给 PDOStatement 查询不会 return 正确的结果,相反,如果我只给出一个参数,它给出了正确的结果。

代码如下:

public function query($sql, $params = NULL) {
        // Opens the PDO connection
        $this->open();

        $this->stmt = $this->pdo->prepare($sql);

        if (isset($params)) {
            foreach ($params as $key => $value) {
                // This doesn't work after the second cicle.
                $this->stmt->bindParam(':' . $key, $value);
            }
        }

        $result = NULL;
        if (!$this->stmt->execute()) {
            $result = false;
        } else {
            $result = $this->stmt->fetchAll();
        }

        // Closes the PDO connection
        $this->close();

        return $result;
}

这是 PDOStatement::debugDumpParams:

SQL: [114]
SELECT 1
FROM   users
WHERE  EXISTS
       (
              SELECT *
              FROM   users
              WHERE  username = :username
              AND    password = :password) limit 1
PARAMS: 2
KEY:NAME: [9] :username paramno=0 NAME=[9] ":username" is_param=1 param_type=2
KEY:NAME: [9] :password paramno=1 NAME=[9] ":password" is_param=1 param_type=2  

感谢您的帮助!

TL;DR 总是使用 bindValue() 除非你想使用 bindParam().

的特殊行为
foreach ($params as $key => $value) {
    // This doesn't work after the second cicle.
    $this->stmt->bindParam(':' . $key, $value);
}

这不能按预期工作的原因是对 bindParam() 的 PDO 含义的误解。这并不意味着 "bind the SQL parameter",而是 "bind the value (i.e. the parameter for bindParam()) as referenced variable"。因此,当 execute() 被调用时,它将在执行时使用 $value 的值(这是绑定到所有 SQL 参数的变量),而不是在 bindParam() 被调用时打电话。

比照。 http://php.net/manual/en/pdostatement.bindparam.php 解释此行为的位置。

解决方案是使用bindValue()代替bindParam()