PDO bindParam ведет себя странно - PullRequest
2 голосов
/ 11 февраля 2011

У меня проблема с корректной работой PDO bindParam. Используя этот код:

$foo = "bar";

$stmt_1 = $db->prepare("SELECT * FROM table WHERE foo = $foo");
$stmt_1->execute();
$results_1 = $stmt_1->fetchAll();

$stmt_2 = $db->prepare("SELECT * FROM table WHERE foo = ?");
$stmt_2->bindParam(1, $foo, PDO::PARAM_STR);
$stmt_2->execute();
$results_2 = $stmt_2->fetchAll();

$stmt_3 = $db->prepare("SELECT * FROM table WHERE foo = :foo");
$stmt_3->bindParam(":foo", $foo, PDO::PARAM_STR);
$stmt_3->execute();
$results_3 = $stmt_3->fetchAll();

$ results_1 содержит только строки, в которых foo = bar, $ results_2 пусто, а $ results_3 содержит каждую запись в «таблице»

У bindValue точно такая же проблема. Кто-нибудь знает, что здесь происходит или что я делаю не так?

Ответы [ 3 ]

1 голос
/ 14 февраля 2011

(Я сделаю новый ответ, потому что я неправильно понял вопрос в другом.)

По умолчанию PDO автоматически игнорирует ошибки и возвращает пустые результаты.Это могло бы объяснить # 2.Например, если ваша таблица действительно называется «таблицей» и вы не заключили ее в кавычки (table - зарезервированное ключевое слово).Включите отчеты об ошибках, чтобы увидеть, так ли это (см. Ниже).

В # 3 все строки могут быть возвращены, потому что условие тавтологическое: foo = foo или :foo = :foo или 'foo' = :foo.

Вот полная программа, которая работает правильно для меня.Если это не работает для вас, это, вероятно, ошибка в определенной версии PHP, PDO или MySQL.

<?php

$db = new PDO('mysql:host=localhost;dbname=test', 'user', 'password');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$foo = 'bar';

$stmt_1 = $db->prepare("SELECT * FROM `table` WHERE foo = '$foo'");
$stmt_1->execute();
$results_1 = $stmt_1->fetchAll();

$stmt_2 = $db->prepare("SELECT * FROM `table` WHERE foo = ?");
$stmt_2->bindParam(1, $foo, PDO::PARAM_STR);
$stmt_2->execute();
$results_2 = $stmt_2->fetchAll();

$stmt_3 = $db->prepare("SELECT * FROM `table` WHERE foo = :foo");
$stmt_3->bindParam("foo", $foo, PDO::PARAM_STR);
$stmt_3->execute();
$results_3 = $stmt_3->fetchAll();

print_r($results_1);
print_r($results_2);
print_r($results_3);
1 голос
/ 15 февраля 2011

Я решил свою проблему.По какой-то причине переменные, которые я устанавливал из $ _POST, были недоступны для внутренних функций определенного мной класса, поэтому я добавил в класс массив параметров для хранения связанных переменных, и теперь все работает.

0 голосов
/ 11 февраля 2011

foo = ? с параметром "bar" эквивалентно foo = 'bar', а не foo = bar.
Т.е. вы выбираете, где столбец равен строке, а не другому столбцу.

Здесь нет необходимости использовать параметр, потому что $foo не вводится пользователем. (Если это так, его следует проверить по конечному набору столбцов в таблице.)


По сути, выполнение SQL-запроса состоит из двух этапов: анализ и оценка. Внедрение SQL может произойти только тогда, когда вы предоставляете парсер для пользовательского ввода. Оценка безопасна независимо от значений в столбцах.

Поэтому, когда вы запускаете WHERE foo = bar;, он анализируется как «сравнить столбцы foo и bar». Это единственное, что будет делать база данных, независимо от значений в этих столбцов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...