Почему эти подготовленные заявления не работают? - PullRequest
0 голосов
/ 22 декабря 2009

Я использую NetBeans 6.8 и у меня на компьютере Mac есть MAMP с этой конфигурацией:

Apache 2.0.63
MySQL 5.1.37
PHP 4.4.9 & 5.2.10
APC 3.0.19 & APC 3.1.2
eAccelerator 0.9.5.3
XCache 1.2.2
phpMyAdmin 2.11.9.5 & phpMyAdmin 3.2.0.1
Zend Optimizer 3.3.3
SQLiteManager 1.2.0
Freetype 2.3.9
t1lib 5.1.2
curl 7.19.5
jpeg 7
libpng-1.2.38
gd 2.0.34
libxml 2.7.3
libxslt 1.1.24
gettext 0.17
libidn 1.15
iconv 1.13
mcrypt 2.5.8
YAZ 3.0.47 & PHP/YAZ 1.0.14

Мой драйвер PDO для MySQL - это версия клиентской библиотеки 5.1.37

Я пытаюсь использовать готовые утверждения здесь.

Это прекрасно работает БЕЗ подготовленных утверждений:

try {
    $dbh = new PDO('mysql:host=localhost;dbname=test', 'root', 'root');
    $prepared = $dbh->prepare('SELECT * from sys_navigation_point WHERE name="root"');
    //$prepared->bindParam('foo', 'root');

    $prepared->execute();

    foreach($prepared as $row) {
        print_r($row);
    }
    $dbh = null;
} catch (PDOException $e) {
    print "Error!: " . $e->getMessage() . "<br/>";
    die();
}

Но это не работает с готовым утверждением. Получая полностью пустую страницу при этом:

try {
    $dbh = new PDO('mysql:host=localhost;dbname=test', 'root', 'root');
    $prepared = $dbh->prepare('SELECT * from sys_navigation_point WHERE name=:foo');
    $prepared->bindParam('foo', 'root');

    $prepared->execute();

    foreach($prepared as $row) {
        print_r($row);
    }
    $dbh = null;
} catch (PDOException $e) {
    print "Error!: " . $e->getMessage() . "<br/>";
    die();
}

foo следует заменить на root. Однако это не так. Итак, давайте попробуем это, что также не работает вообще:

try {
    $dbh = new PDO('mysql:host=localhost;dbname=test', 'root', 'root');
    $prepared = $dbh->prepare('SELECT * from sys_navigation_point WHERE name=?');
    $prepared->bindParam(1, 'root');

    $prepared->execute();

    foreach($prepared as $row) {
        print_r($row);
    }
    $dbh = null;
} catch (PDOException $e) {
    print "Error!: " . $e->getMessage() . "<br/>";
    die();
}

Абсолютно ничего. Я даже не получаю сообщение об ошибке. Просто пустая страница. После этого кода есть некоторое эхо со стандартным выводом HTML. Он не выходит, поэтому скрипт останавливается где-то рядом с вызовом метода bindParam.

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

try {
    $dbh = new PDO('mysql:host=localhost;dbname=test', 'root', 'root');
    $prepared = $dbh->prepare('SELECT * from sys_navigation_point WHERE name="root"');
    //$prepared->bindParam('foo', 'root');

    $prepared->execute();

    foreach($prepared as $row) {
        print_r($row);
    }
    $dbh = null;
} catch (PDOException $e) {
    print "Error!: " . $e->getMessage() . "<br/>";
    die();
}

Как вы можете видеть, очевидно, что все версии - это один и тот же запрос. С PS не работает. Без PS это делает. Теперь я нашел брутальную ошибку в самом PHP?

Возможно ли, что подготовленные операторы где-то отключены?

Ответы [ 2 ]

3 голосов
/ 22 декабря 2009

Вы используете этот вид кода:

$prepared->bindParam('foo', 'root');

Но bindParam ожидает переменную в качестве второго параметра:

bool PDOStatement::bindParam  ( mixed $parameter  , 
    mixed &$variable  [, int $data_type = PDO::PARAM_STR  [, int $length  
    [, mixed $driver_options  ]]] )


Здесь вам, вероятно, следует использовать bindValue, поскольку вы хотите связать только ... значение ..., а не переменную, переданную по ссылке на запрос SQL:

bool PDOStatement::bindValue  ( mixed $parameter  , mixed $value  
    [, int $data_type = PDO::PARAM_STR  ] )

Итак, ваш код будет выглядеть так:

$prepared->bindValue(':foo', 'root');

(Не забывайте ':' перед именем параметра, кстати ;-))

2 голосов
/ 22 декабря 2009

Имя привязки :foo - не foo. И вы не должны использовать bindParam, но bindValue, так как вы не указываете переменную в качестве аргумента. Например. :

$prepared->bindValue(':foo', 'root');

В общем, я бы порекомендовал вам никогда использовать bindParam, поскольку он имеет эталонную семантику и, следовательно, может создавать некоторые действительно трудно обнаруживаемые ошибки.

...