0

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

这是代码:

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  

感谢您的帮助!

4

1 回答 1

1

TL;DR 始终使用bindValue(),除非您想使用bindParam().

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

这不能按预期工作的原因是对 PDO 含义的误解bindParam()。这并不意味着“绑定 SQL 参数”,而是“将值(即bindParam()的参数)绑定为引用变量”。因此,当execute()被调用时,它将$value在执行时使用值 for(这是绑定到所有 SQL 参数的变量),而不是在bindParam()调用时。

参照。http://php.net/manual/en/pdostatement.bindparam.php解释了这种行为。

解决方案是使用bindValue()而不是bindParam().

于 2018-10-15T13:19:50.487 回答