Есть ли разница между подготовленными запросами в PDO и SQLite3?

Я рву на себе волосы весь день с этим. Я вижу одинаковое поведение как в Windows, так и в Linux.

Простые примеры на этом и других сайтах прекрасно демонстрируют работу параметризованных запросов с SQLite (с использованием класса SQLite3). Однако те же примеры не работают при использовании класса PDO — они возвращают нулевые строки. Я не могу найти никакой причины для этого.

Вот мой тестовый PHP-скрипт, который делает одно и то же дважды — один раз через SQLite3, а затем через PDO. Первый возвращает вставленную строку, а второй нет, хотя вставленная строка существует в базе данных. Что я делаю неправильно?

<?php
echo "connecting via SQLite3<BR>";

unlink('mysqlitedb.db');
$db = new SQLite3('mysqlitedb.db');

$db->exec('CREATE TABLE foo (id INTEGER, bar STRING)');
$db->exec("INSERT INTO foo (id, bar) VALUES (1, 'This is a test')");

$stmt = $db->prepare('SELECT bar FROM foo WHERE id=:id');
$stmt->bindValue(':id', 1, SQLITE3_INTEGER);

$result = $stmt->execute();
var_dump($result->fetchArray());

echo "<P>Connecting via PDO<BR>";

unlink('mysqlitepdo.db');
$db = new PDO('sqlite:mysqlitepdo.db');

$db->exec('CREATE TABLE foo (id INTEGER, bar STRING)');
$db->exec("INSERT INTO foo (id, bar) VALUES (1, 'This is a test')");

$stmt = $db->prepare('SELECT bar FROM foo WHERE id=:id');
$stmt->bindValue(':id', 1, SQLITE3_INTEGER);

$result = $stmt->execute();
var_dump($result->fetchArray());

?>

Когда этот скрипт выполняется, он возвращает:

connecting via SQLite3
array(2) { [0]=> string(14) "This is a test" ["bar"]=> string(14) "This is a test" }
Connecting via PDO

Fatal error: Call to a member function fetchArray() on a non-object in D:\docs\LRRSA\LRRSA_site\MCC\foobar.php on line 28

Я предполагаю, что фатальная ошибка вызвана тем, что для varDump не возвращаются строки.

Я уверен, что это что-то очевидное, но если так, то это слишком очевидно для меня :-)


person John Dennis    schedule 30.12.2015    source источник


Ответы (1)


Библиотеки (SQLite и PDO) семантически почти одинаковы, но внутри есть некоторые различия.

Например, с PDO метод execute() PDOStatement возвращает либо false или true, а не набор результатов. Итак, когда вы делаете:

$result->fetchArray();

Вы в основном делаете:

true->fetchArray();

Это, конечно, недопустимый метод (поскольку true не имеет никаких методов, будучи логическим). Вы можете получить результаты из выполненного оператора PDO с помощью метода fetchAll() на само заявление:

$stmt->fetchAll();
person Oldskool    schedule 30.12.2015
comment
Спасибо. Это, безусловно, работает, хотя я никогда раньше не использовал fetchAll() и всегда подключался к базе данных с помощью PDO. Единственное различие между этим, которое я часто использовал: $qq = $db-›prepare($sql); $qq-›execute(array()) or die(print_r($db-›errorInfo(), true)); foreach($qq as $row) { ..... } и который отлично работает, это bindValue() между prepare() и execute(). Завтра я потрачу больше времени на проверку доступа к PDO. - person John Dennis; 30.12.2015
comment
Теперь я понимаю, что я сделал не так. Я подключился к PDO, но затем искал помощь с запросами, сосредоточенными на SQLite, а не на PDO. - person John Dennis; 03.01.2016