Клонирование объекта набора записей PHP PDO для подсчета строк, возвращаемых оператором select - PullRequest
2 голосов
/ 22 января 2011

Я выполняю рефакторинг части приложения PHP, которое использует adodb в качестве библиотеки db, чтобы начать использовать PDO.

Мне нужно что-то, что дает мне количество строк, включенных в набор записей select, что-то, что может легко заменить старый метод $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 нет способа повторно использовать набор записей (поправьте меня, если я ошибаюсь).

У вас есть какие-нибудь решения?

Ответы [ 4 ]

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

Использование SELECT COUNT(*) FROM запуска в качестве второго запроса - это рекомендуемый способ подсчета количества строк в наборе результатов при использовании LIMIT в основном запросе. Он не будет извлекать одни и те же данные дважды, он просто считает, сколько строк найдено, и возвращает 1 строку, целое число. Другой способ узнать количество строк при использовании оператора LIMIT - использовать SELECT SQL_CALC_FOUND_ROWS (field list) FROM ... в первом запросе, а затем выполнить SELECT FOUND_ROWS(), чтобы получить количество строк, однако этот метод медленнее, чем предыдущий. Имейте в виду, что выполнение count() в PHP даст только количество возвращенных строк, а не фактическое количество строк, найденных в базе данных (если вы используете LIMIT).

Приветствия

0 голосов
/ 22 января 2011

Возможно, возможно сделать так, как предлагает col shrapnel, и сохранить результат в массиве. Вы можете поддерживать интерфейс в чистоте, расширив PDOStatement, а затем

http://www.php.net/manual/en/pdo.setattribute.php PDO :: ATTR_STATEMENT_CLASS

Так он вернет вам EugenioEnhancedPDOStatement

0 голосов
/ 22 января 2011

Спасибо всем.Я нашел более простое, быстрое и грязное решение, мой новый get_num_rows() будет выглядеть примерно так:

$temp_ar = explode("FROM", $rs->queryString);

$sql = "SELECT COUNT(*) FROM ".$temp_ar[1];

$conn->query($sql);

...
0 голосов
/ 22 января 2011

Нельзя правильно клонировать и / или сериализовать / десериализовать объекты PDO, скорее всего потому, что они тесно связаны с ресурсом соединения.

Дело в том, что нет смысла клонировать его.Если $rs является объектом PDOStatement, вы можете просто повторно выполнить его, так как у вас есть доступ к нему.Это одно из основных преимуществ подготовленных операторов: подготовить один раз, выполнить несколько раз .

Примерно так:

function get_num_rows($rs)
{
 $rs->execute();
 return (count($rs->fetchAll()));
}

Вы уже догадались: вызов execute () на том же экземпляре PDOStatement второй раз без указания каких-либо параметров будет повторно использовать последний набор параметров и повторно выполнять оператор как есть.

Следовательно, существуетнет необходимости клонировать объекты PDOStatement.

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