Количество строк с PDO - PullRequest
176 голосов
/ 19 мая 2009

Вокруг много противоречивых утверждений. Каков наилучший способ подсчета строк с использованием PDO в PHP? Перед использованием PDO я просто использовал mysql_num_rows.

fetchAll - это то, чего я не хочу, потому что иногда я имею дело с большими наборами данных, поэтому это не подходит для моего использования.

Есть ли у вас какие-либо предложения?

Ответы [ 22 ]

242 голосов
/ 19 мая 2009
$sql = "SELECT count(*) FROM `table` WHERE foo = bar"; 
$result = $con->prepare($sql); 
$result->execute(); 
$number_of_rows = $result->fetchColumn(); 

Не самый элегантный способ сделать это, плюс он требует дополнительного запроса.

PDO имеет PDOStatement::rowCount(), что, очевидно, не работает в MySql. Что за боль.

Из документа PDO:

Для большинства баз данных PDOStatement :: rowCount () не делает вернуть количество строк, затронутых оператор SELECT. Вместо этого используйте PDO :: query () для выдачи SELECT COUNT (*) оператор с тем же предикаты как ваш намеченный SELECT заявление, а затем использовать PDOStatement :: fetchColumn () для получить количество строк, которые будут быть возвращенным. Ваша заявка может затем выполнить правильное действие.

РЕДАКТИРОВАТЬ: В приведенном выше примере кода используется подготовленный оператор, который во многих случаях, вероятно, не нужен для подсчета строк, поэтому:

$nRows = $pdo->query('select count(*) from blah')->fetchColumn(); 
echo $nRows;
82 голосов
/ 19 мая 2009

Как я уже писал ранее в ответ на аналогичный вопрос , единственная причина, по которой mysql_num_rows() работал, заключается в том, что он внутренне выбирал все строки, чтобы дать вам эту информацию, даже если она не показалась нравится тебе.

Итак, в PDO, ваши варианты:

  1. Используйте функцию MySQL FOUND_ROWS().
  2. Используйте функцию PDO fetchAll() для извлечения всех строк в массив, а затем используйте count() для него.
  3. Сделайте дополнительный запрос к SELECT COUNT(*), как предложил karim79.
21 голосов
/ 27 мая 2013

Перед использованием PDO я просто использовал mysql_num_rows().

Вы не должны были использовать его .

mysql_num_rows(), а также PDOStatement::rowCount() означает, что вы уже выбрали свои данные. В этом случае есть только два возможных варианта использования такой функции:

  1. Вы выбирали свои данные только для подсчета.
  2. Вы хотите знать, возвращал ли ваш запрос какие-либо строки.

И первый никогда не должен использоваться вообще. Никогда не следует выбирать строки для их подсчета, поскольку ваш сервер действительно может задохнуться из-за большого набора возвращаемых данных.

Кроме того, выбирать строки только для их подсчета просто бессмысленно. Вместо этого необходимо выполнить запрос count(*), с возвращением только одной строки.

Второй вариант использования менее катастрофичен, но довольно бессмысленен: если вам нужно узнать, возвращал ли ваш запрос какие-либо данные, у вас всегда есть эти данные!

Скажем, если вы выбираете только одну строку, просто извлеките ее и проверьте результат:

$stmt->execute();
$row = $stmt->fetch();
if ($row) { // here! as simple as that
}

Если вам нужно получить много строк, вы можете использовать fetchAll().

fetchAll() - это то, чего я не хочу, так как иногда я имею дело с большими наборами данных

Обратите внимание, что в веб-приложении никогда не следует выделять огромное количество строк. Только строки, которые будут фактически использоваться на веб-странице, должны быть выбраны. Для этой цели необходимо использовать LIMIT или аналогичное предложение в SQL. И для такого небольшого количества данных можно использовать fetchAll()

В таком редком случае, когда вам нужно выбрать действительно огромное количество строк (например, в консольном приложении), чтобы уменьшить объем используемой памяти, вы должны использовать небуферизованный запрос, но в этом случае rowCount() будет недоступно в любом случае , поэтому эта функция также не используется.

Итак, вы видите, что нет ни одного варианта использования ни для rowCount(), ни для дополнительного запроса для его замены, как предлагается в принятом ответе.

19 голосов
/ 06 марта 2013

Это супер поздно, но я столкнулся с проблемой, и я делаю это:

function countAll($table){
   $dbh = dbConnect();
   $sql = "select * from `$table`";

   $stmt = $dbh->prepare($sql);
    try { $stmt->execute();}
    catch(PDOException $e){echo $e->getMessage();}

return $stmt->rowCount();

Это действительно просто и легко. :)

18 голосов
/ 31 июля 2011

Я использовал это:

$result = $db->query($query)->fetchAll();

if (count($result) > 0) {
    foreach ($result as $row) {
        echo $row['blah'] . '<br />';
    }
} else {
    echo "<p>Nothing matched your query.</p>";
}
8 голосов
/ 23 июля 2014

Этот пост старый, но Получить количество строк в php с помощью PDO просто

$stmt = $db->query('SELECT * FROM table');
$row_count = $stmt->rowCount();
5 голосов
/ 14 июля 2010

Это старый пост, но он разочарован поиском альтернативы. Очень жаль, что в PDO нет этой возможности, тем более что PHP и MySQL стремятся идти рука об руку.

К сожалению, в fetchColumn () есть недостаток, поскольку вы больше не можете использовать этот набор результатов (эффективно), поскольку fetchColumn () перемещает стрелку к следующей строке. Так, например, если у вас есть результат, похожий на

  1. фруктовое> Banana
  2. фруктовое> Apple,
  3. фруктовое> Orange

Если вы используете fetchColumn (), вы можете узнать, что возвращены 3 плода, но если вы теперь просматриваете результат в цикле, у вас есть только два столбца. просто чтобы узнать, сколько строк было возвращено. Это приводит к небрежному кодированию и полностью ошибочным результатам, если они реализованы.

Так что теперь, используя fetchColumn (), вы должны реализовать и совершенно новый вызов и запрос MySQL только для того, чтобы получить новый рабочий набор результатов. (что, надеюсь, не изменилось со времени вашего последнего запроса), я знаю, вряд ли, но это может произойти. Кроме того, накладные расходы двойных запросов на проверку всех строк. Что для этого примера невелико, но анализирует 2 миллиона строк в объединенном запросе, а это не приятная цена.

Я люблю PHP и поддерживаю всех, кто участвует в его разработке, а также сообщество в целом, использующих PHP на ежедневной основе, но очень надеюсь, что это будет решено в будущих выпусках. Это «действительно» моя единственная жалоба с PHP PDO, которая в противном случае - отличный класс.

2 голосов
/ 10 августа 2014

Отвечая на это, потому что теперь я поймал себя в ловушку, зная это, и, возможно, это будет полезно.

Имейте в виду, что вы не можете получить результаты дважды. Вы должны сохранить результат выборки в массив, получить количество строк на count($array) и вывести результаты с помощью foreach. Например:

$query = "your_query_here";
$STH = $DBH->prepare($query);
$STH->execute();
$rows = $STH->fetchAll();
//all your results is in $rows array
$STH->setFetchMode(PDO::FETCH_ASSOC);           
if (count($rows) > 0) {             
    foreach ($rows as $row) {
        //output your rows
    }                       
}
1 голос
/ 13 апреля 2017

Посмотрите на эту ссылку: http://php.net/manual/en/pdostatement.rowcount.php Не рекомендуется использовать rowCount () в инструкциях SELECT!

1 голос
/ 11 июня 2016

Если вы просто хотите получить количество строк (не данных), т.е. используя COUNT (*) в подготовленном выражении, все, что вам нужно сделать, это получить результат и прочитать значение:

$sql = "SELECT count(*) FROM `table` WHERE foo = bar";
$statement = $con->prepare($sql); 
$statement->execute(); 
$count = $statement->fetch(PDO::FETCH_NUM); // Return array indexed by column number
return reset($count); // Resets array cursor and returns first value (the count)

На самом деле получение всех строк (данных) для простого подсчета является пустой тратой ресурсов. Если набор результатов велик, ваш сервер может подавиться им.

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