Посчитать, сколько элементов лежит в инфоблоке (или удовлетворяет фильтру), в 1С-Битрикс можно несколькими способами. Главное – не выбирать все элементы и не считать их через count() в PHP: это лишняя нагрузка. Считать нужно на стороне БД. Ниже – три рабочих приёма, от самого чистого к легаси-варианту из исходной заметки.
Способ 1 (рекомендуемый): CIBlockElement::GetCount
Отдельный метод, который сразу возвращает число – читается однозначно и не путается с выборкой:
CModule::IncludeModule("iblock");
$count = CIBlockElement::GetCount([
"IBLOCK_ID" => 19, // ID инфоблока
"ACTIVE" => "Y", // только активные
"ACTIVE_DATE" => "Y", // с учётом дат активности
]);
echo intval($count);
Это самый явный вариант: GetCount() принимает только фильтр и возвращает целое число. Рекомендую использовать именно его для новых доработок.
Способ 2: GetList с пустым arGroupBy
Именно этот приём был в исходной заметке. Он работает благодаря особенности GetList: если третьим аргументом ($arGroupBy) передать пустой массив, метод вернёт не объект выборки, а целое число – количество найденных записей:
CModule::IncludeModule("iblock");
$arFilter = ["IBLOCK_ID" => 19, "ACTIVE" => "Y"];
$count = CIBlockElement::GetList([], $arFilter, []); // 3-й аргумент – пустой массив!
echo intval($count);
Важно про исходный код. В старой версии было CIBlockElement::GetList(Array(), $arFilter, Array(), false, Array()) и echo $res_count. Это действительно работает – но только потому, что третий аргумент Array() переключает метод в режим подсчёта. Если случайно убрать этот пустой массив (или передать вместо него false), GetList вернёт объект результата, и echo выведет что-то вроде Object вместо числа. Поэтому способ 1 надёжнее: там перепутать нечего.
Если у вас уже есть объект выборки
Когда выборка уже сделана для вывода элементов, повторно считать не нужно – количество отдаст метод результата SelectedRowsCount():
$res = CIBlockElement::GetList([], $arFilter, false, false, ["ID"]);
echo $res->SelectedRowsCount();
Способ 3 (D7): ElementTable::getCount
В актуальных версиях Битрикса тот же подсчёт делается через ORM – коротко и типизированно:
use Bitrix\Iblock\ElementTable;
$count = ElementTable::getCount([
'=IBLOCK_ID' => 19,
'=ACTIVE' => 'Y',
]);
echo $count;
Метод getCount() есть у любой ORM-сущности Битрикса (наследник DataManager) и возвращает целое число. Классические GetCount/GetList при этом остаются полностью рабочими – выбор за стилем проекта.
Замечания по производительности и точности
- Считайте в БД, а не в PHP. Никогда не делайте выборку всех элементов только ради
count()– используйтеGetCount/getCount. - Учитывайте даты активности. Фильтр
ACTIVE => "Y"не отсекает элементы с ещё не наступившей или истёкшей датой активности. Чтобы «активные прямо сейчас» – добавьтеACTIVE_DATE => "Y". - Права доступа. Классические методы по умолчанию учитывают права; для подсчёта без учёта прав в фильтр можно добавить
"CHECK_PERMISSIONS" => "N". - Кэш. Если число выводится часто и меняется редко, оберните подсчёт в управляемый кэш (
\Bitrix\Main\Data\Cache), чтобы не бить в БД на каждый показ.
Похожие задачи: как посчитать элементы внутри раздела, как задать число результатов поиска по новостям и как выбрать элемент и его свойства по ID из GET.