PDOStatement :: bindParam не работает после первого вызова - PullRequest
0 голосов
/ 14 октября 2018

У меня небольшая проблема при написании простого класса, который использует PDO для подключения к БД.
Проблема в том, что PDOStatement :: bindParam не работает после первого вызова в цикле, я имею в виду, если у меня естьдва параметра для передачи в PDOStatement запрос не возвращает точный результат, вместо этого, если я даю только один параметр, он дает правильный результат.

Вот код:

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  

Спасибо за помощь!

1 Ответ

0 голосов
/ 15 октября 2018

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 (которое является переменной, связанной со всеми параметрами SQL) во время выполнения, а не во время вызова bindParam().

Cf.http://php.net/manual/en/pdostatement.bindparam.php, где это поведение объясняется.

Решение состоит в том, чтобы использовать bindValue() вместо bindParam().

...