Як це часто буває, це питання бентежить як пекло. Люди приходять сюди, маючи на увазі два різні завдання :
- Їм потрібно знати, скільки рядків у таблиці
- Вони повинні знати, чи повертав запит якісь рядки
Це дві абсолютно різні задачі, які не мають нічого спільного і не можуть бути вирішені однією і тією ж функцією. Як не дивно, для жодної з них фактична 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()
він не буде доступний , тому для цієї функції також немає користі.
Отже, це єдиний випадок використання, коли, можливо, вам доведеться запустити додатковий запит, якщо вам потрібно знати приблизну оцінку кількості вибраних рядків.