Как это часто бывает, этот вопрос чертовски запутан. Люди приходят сюда, имея в виду две разные задачи :
- Они должны знать, сколько строк в таблице
- Они должны знать, возвращал ли запрос какие-либо строки
Это две абсолютно разные задачи, которые не имеют ничего общего и не могут быть решены одной и той же функцией. По иронии судьбы, ни для одного из нихPDOStatement::rowCount()
нельзя использовать фактическую функцию.
Посмотрим почему
Подсчет строк в таблице
До использования PDO я просто пользовался mysql_num_rows()
.
Значит, ты уже сделал это неправильно. Использование mysql_num_rows()
или rowCount()
для подсчета количества строк в таблице является настоящей катастрофой с точки зрения использования ресурсов сервера. База данных должна прочитать все строки с диска, использовать память на сервере базы данных, а затем отправить всю эту кучу данных в PHP, также потребляя память процесса PHP, обременяя ваш сервер без всякой причины.
Кроме того, выбирать строки только для их подсчета просто бессмысленно. count(*)
Запрос должен быть запущен вместо этого. База данных будет считать записи из индекса, не считывая фактические строки, а затем вернет только одну строку.
Для этого код, предложенный в принятом ответе, является справедливым.
Подсчет количества возвращенных строк.
Второй вариант использования не так катастрофичен, как довольно бессмысленный: в случае, если вам нужно знать, вернул ли ваш запрос какие-либо данные, у вас всегда есть эти данные!
Скажем, если вы выбираете только одну строку. Хорошо, вы можете использовать выбранную строку в качестве флага:
$stmt->execute();
$row = $stmt->fetch();
if (!$row) { // here! as simple as that
echo 'No data found';
}
В случае, если вам нужно получить много строк, вы можете использовать fetchAll()
.
fetchAll()
это то, чего я не хочу, так как иногда я имею дело с большими наборами данных
Да, конечно, для первого варианта использования это будет в два раза хуже. Но , как мы уже знаем, просто не выбрать строки только сосчитать, ни с rowCount()
ниfetchAll()
.
Но если вы собираетесь использовать выбранные строки, в этом нет ничего плохого fetchAll()
. Помните, что в веб-приложении никогда не следует выделять огромное количество строк. Только строки, которые будут фактически использоваться на веб-странице, должны быть выбраны, следовательно, вы должны использовать LIMIT
, WHERE
или аналогичное предложение в вашем SQL. И для такого умеренного количества данных все в порядке fetchAll()
. И снова, просто используйте результат этой функции в условии:
$stmt->execute();
$data = $stmt->fetchAll();
if (!$data) { // again, no rowCount() is needed!
echo 'No data found';
}
И, конечно, это будет абсолютное безумие, чтобы выполнить дополнительный запрос только для того, чтобы узнать, вернул ли ваш другой запрос какие-либо строки, как это было предложено в двух главных ответах.
Подсчет количества строк в большом наборе результатов
В таком редком случае, когда вам нужно выбрать действительно огромное количество строк (например, в консольном приложении), вы должны использовать небуферизованный запрос , чтобы уменьшить объем используемой памяти. Но это тот самый случай, когда rowCount()
не будет доступно , поэтому эта функция также бесполезна.
Следовательно, это единственный случай использования, когда вам может потребоваться выполнить дополнительный запрос, если вам нужно знать приблизительную оценку количества выбранных строк.