#php #sqlite #pdo
#php #sqlite #pdo
Вопрос:
Я рефакторингую часть PHP-приложения, которое использует adodb в качестве библиотеки db, чтобы начать использовать PDO.
Мне нужно что-то, что предоставляет мне количество строк, включенных в выбранный набор записей, что-то, что может легко заменить старый $rs->RecordCount()
метод adodb, который я использовал ранее. Это должно работать для sqlite3.
Я не могу просто повторно выполнить запрос (или повторно выполнить запрос с помощью select count(*)
), потому что я не могу так сильно изменить исходное приложение, приложение вызывает во многих частях функцию get_num_rows($rs)
(которая содержит только $rs->RecordCount()
), и я могу просто изменить содержимое этой функции.
Я попробовал клонировать объект набора записей и подсчитать извлеченные записи:
function get_num_rows($rs)
{
$rs_copy = clone $rs;
return (count($rs_copy->fetchAll()));
}
но это не работает, потому что $rs_copy->fetchAll()
возвращает меня false
. Я не могу сделать это для исходного набора записей, потому что позже в приложении мне нужно будет извлечь его снова, и я думаю, что в PDO sqlite нет способа повторно использовать набор записей (поправьте меня, если я ошибаюсь).
Есть ли у вас какие-либо решения?
Комментарии:
1. Что вы пытаетесь получить? Количество всех строк для реализации разбивки на страницы или количество возвращенных строк?
2. @nikic:
$result -> rowCount ()
работает только для обновлений.3. Пожалуйста, попробуйте это для клонирования $rs_copy = несериализовать(serialize($ rs));
4. @Gaurav: Объекты PDO не могут быть сериализованы.
5. Вам не нужно ни подсчитывать количество строк, ни выполнять другую выборку позже в приложении . Просто сразу извлеките его в массив, а затем используйте функцию count(). Если вы не можете изменить окружающий код, вам лучше оставить текущий ADODB в покое
Ответ №1:
Использование SELECT COUNT(*) FROM
run в качестве второго запроса — рекомендуемый способ подсчета количества строк в результирующем наборе при использовании LIMIT
в вашем основном запросе. Он не будет извлекать одни и те же данные дважды, он просто подсчитывает, сколько найдено строк, и возвращает 1 строку, целое число. Другой способ определить количество строк при использовании LIMIT
инструкции — использовать SELECT SQL_CALC_FOUND_ROWS (field list) FROM ...
в вашем первом запросе, затем выполнить SELECT FOUND_ROWS()
, чтобы получить количество строк, однако этот метод работает медленнее, чем предыдущий упомянутый. Имейте в виду, что запуск count()
на PHP выдаст вам только количество возвращенных строк, а не фактическое количество строк, найденных в базе данных (если вы используете LIMIT
).
Приветствия
Ответ №2:
Возможно, есть возможность поступить так, как предложил col shrapnel, и сохранить результат в массиве. Возможно, вам удастся сохранить интерфейс чистым, расширив PDOStatement, а затем
http://www.php.net/manual/en/pdo.setattribute.php PDO::ATTR_STATEMENT_CLASS
Таким образом, он вернет вам EugenioEnhancedPDOStatement
Ответ №3:
Спасибо всем. Я нашел более простое, быстрое и грязное решение, мое новое get_num_rows()
будет чем-то вроде:
$temp_ar = explode("FROM", $rs->queryString);
$sql = "SELECT COUNT(*) FROM ".$temp_ar[1];
$conn->query($sql);
...
Комментарии:
1. используйте третий аргумент для explode(), чтобы он разделялся только один раз.
Ответ №4:
Вы не можете должным образом клонировать и / или сериализовать / несериализовать объекты PDO, скорее всего, потому, что они тесно привязаны к ресурсу подключения.
Дело в том, что клонировать его нет смысла. Если $rs
это объект PDOStatement, вы можете просто повторно выполнить его, поскольку у вас есть к нему доступ. Это одно из основных преимуществ подготовленных инструкций, подготавливается один раз, выполняется несколько раз.
Вот так:
function get_num_rows($rs)
{
$rs->execute();
return (count($rs->fetchAll()));
}
Вы догадались: вызов execute() в том же экземпляре PDOStatement во второй раз без указания каких-либо параметров приведет к повторному использованию последнего набора параметров и повторному выполнению инструкции как есть.
Следовательно, нет необходимости клонировать объекты PDOStatement.
Комментарии:
1. Эта извращенная задача (дважды извлекать одни и те же данные только для того, чтобы их посчитать), конечно, не для того, для чего был изобретен PDO.
2. @Col. Shrapnel: Я согласен, что это не так, и я никогда не говорил, что это так. Я отвечаю на вопрос OP. Конечно, это не оптимально: но я не собираюсь переписывать весь его код за него. Если у вас есть лучшее наглядное решение этой проблемы, я хотел бы увидеть его в ответе. Возможно, я даже проголосую за это. 🙂
3. Я так и не нашел решения проблемы, в которой не вижу смысла
4. Я не понимаю, почему вы не видите в этом смысла, мне просто нужно получить количество строк в функции, не касаясь всего остального кода.