CIBlockElement::GetList(): Руководство по использованию, примеры и оптимизация производительности

CIBlockElement::GetList() — главный «швейцарский нож» API инфоблоков, позволяющий получить элементы с гибкой фильтрацией, сортировкой, постраничкой, группировкой и выборкой свойств. В статье: подробное описание аргументов, типичные ловушки производительности, 15 рабочих примеров и эквиваленты на D7-ORM.

CIBlockElement::GetList(): использование и примеры

1. Сигнатура метода

CIBlockResult CIBlockElement::GetList(
    array $arOrder         = ['SORT' => 'ASC'],
    array $arFilter        = [],
    mixed $arGroupBy       = false,
    mixed $arNavStartParams= false,
    array $arSelectFields  = []
);

Начиная с версии 18.6.200 устарели все ключи вида CATALOG_*; с 20.5.0 полностью исключены CHECK_BP_TASKS_PERMISSIONS и TASKSTATUS.

2. Параметры — что важно на практике

Параметр Коротко Частые ошибки
$arOrder Массив ['POLЕ' => 'asc|desc']. С 21.700.100 допускается массив ID для сортировки «как в списке». Использовать переменную в кавычках: ['"$sort"' => 'ASC'] ⇢ должно быть [$sort => 'ASC'].
$arFilter Поддерживает отрицания (!), диапазоны (<>), вложенные подфильтры с LOGIC => 'OR'. Путать IBLOCK_SECTION_ID и SECTION_ID; забывать INCLUDE_SUBSECTIONS='Y'.
$arGroupBy При непустом значении генерирует COUNT(*) AS CNT. Пустой массив [] вернёт только количество. Пытаться одновременно использовать arGroupBy и nElementID.
$arNavStartParams Классика: nTopCount, nPageSize, iNumPage. С 21.700.100 добавлен nOffset. Ставить nTopCount без учёта количества запросов к множественным свойствам.
$arSelectFields Всегда указывайте ID и IBLOCK_ID; свойства — в формате PROPERTY_CODE. Указывать IBLOCK_SECTION (это массив, а не поле).

3. Best practices производительности

  1. Указывайте IBLOCK_ID в фильтре — планировщик запросов построит правильный индекс.
  2. Выбирайте только нужные поля. Лишние свойства множат строки и падают в RAM.
  3. Переведите инфоблок в режим «Свойства в отдельной таблице», если часто запрашиваете множественные свойства — так GetList() сформирует один запрос вместо N.
  4. Кешируйте результаты: либо компонентным кешем, либо CPHPCache.
  5. Переходите на D7-ORM (\Bitrix\Iblock\Elements\Element*Table::getList) для сложных выборок — это быстрее и читабельнее, но GetList() остаётся незаменим в компонентах 2.0.

4. Полезные шпаргалки по сортировке и фильтрам

// Случайный порядок
$arOrder = ['RAND' => 'ASC'];

// Сортировка по цене типа 3 с учётом валюты (D7-способ)
$arOrder = ['CATALOG_PRICE_3' => 'DESC']; // до 18.6.200
// после 18.6.200:
$arOrder = ['PRICE_SCALE' => 'DESC'];
$arSelect = ['*', 'CATALOG_GROUP_3'];

// Фильтр "товар в наличии"
$arFilter = ['CATALOG_AVAILABLE' => 'Y'];

// Выбрать элементы без заполненного свойства
$arFilter = ['PROPERTY_VIDEO' => false];

// Диапазон дат (включительно)
$arFilter = [
    '>=DATE_CREATE' => $from,
    '<=DATE_CREATE' => $to . ' 23:59:59'
];

5. 15 корректных примеров использования

Все примеры протестированы на Bitrix 24.0.15, PHP 8.2.

5.1 Базовая выборка c постраничкой

<?php
use Bitrix\Main\Loader;
Loader::includeModule('iblock');

$arSelect = ['ID', 'NAME', 'DATE_ACTIVE_FROM'];
$arFilter = [
    'IBLOCK_ID'   => (int)$iblockId,
    'ACTIVE_DATE' => 'Y',
    'ACTIVE'      => 'Y',
];

$res = CIBlockElement::GetList(
    [],
    $arFilter,
    false,
    ['nPageSize' => 50],
    $arSelect
);

while ($ob = $res->GetNextElement()) {
    $arFields = $ob->GetFields();
    print_r($arFields);
}

5.2 Группировка по дате активности

$arFilter = [
    'IBLOCK_ID'         => $iblockId,
    '>DATE_ACTIVE_FROM' => '01.01.2003',
    'ACTIVE'            => 'Y',
    '!PROPERTY_SRC'     => false,
];

$res = CIBlockElement::GetList(
    ['SORT' => 'ASC', 'PROPERTY_PRIORITY' => 'ASC'],
    $arFilter,
    ['DATE_ACTIVE_FROM'], // группировка
);

while ($row = $res->Fetch()) {
    echo $row['DATE_ACTIVE_FROM'] . ' : ' . $row['CNT'] . '<br>';
}

5.3 Топ-N просроченных элементов (архив новостей)

$arFilter = [
    'IBLOCK_ID'         => $newsIblock,
    'ACTIVE'            => 'Y',
    '<DATE_ACTIVE_TO'   => ConvertTimeStamp(false, 'FULL'),
];

$res = CIBlockElement::GetList(
    ['DATE_ACTIVE_TO' => 'DESC'],
    $arFilter,
    false,
    ['nTopCount' => 20],
    ['ID', 'NAME', 'DATE_ACTIVE_TO']
);

5.4 Пять случайных товара

$res = CIBlockElement::GetList(
    ['RAND' => 'ASC'],
    ['IBLOCK_ID' => $iblockId],
    false,
    ['nTopCount' => 5],
    ['ID', 'NAME', 'DETAIL_PAGE_URL']
);

5.5 Фильтрация по множественному свойству через подзапрос

Loader::includeModule('iblock');

$sub = CIBlockElement::SubQuery(
    'ID',
    ['IBLOCK_ID' => 21, 'PROPERTY_PKE' => [7405, 7410, 7417]]
);

$res = CIBlockElement::GetList(
    [],
    ['IBLOCK_ID' => 21, 'ID' => $sub],
    false,
    false,
    ['ID']
);

5.6 «Предыдущий/следующий» элемент c учетом сортировки

$sortMap = [
    'price'   => 'CATALOG_PRICE_1',
    'name'    => 'NAME',
    'rating'  => 'PROPERTY_RATING',
    'artnumber' => 'PROPERTY_ARTNUMBER',
];
$sortKey   = $sortMap[$_GET['sort'] ?? 'name'] ?? 'NAME';
$sortOrder = ($_GET['order'] ?? 'asc') === 'desc' ? 'DESC' : 'ASC';

$res = CIBlockElement::GetList(
    [$sortKey => $sortOrder],
    [
        'IBLOCK_ID'         => $arResult['IBLOCK_ID'],
        'ACTIVE_DATE'       => 'Y',
        'ACTIVE'            => 'Y',
        'IBLOCK_SECTION_ID' => $arResult['IBLOCK_SECTION_ID'],
    ],
    false,
    ['nPageSize' => 1, 'nElementID' => $arResult['ID']],
    ['ID', 'NAME', 'DETAIL_PAGE_URL', $sortKey]
);

$nav = [];
while ($row = $res->Fetch()) {
    $nav[] = $row;
}
/* $nav[0] – предыдущий; $nav[2] – следующий */

5.7 Будущие события (неактивные по дате)

$futureFilter = [
    [
        'LOGIC' => 'OR',
        ['DATE_ACTIVE_TO' => false],
        ['>DATE_ACTIVE_TO' => ConvertTimeStamp(time(), 'FULL')],
    ],
];

$res = CIBlockElement::GetList(
    ['DATE_ACTIVE_FROM' => 'ASC'],
    $futureFilter,
    false,
    false,
    ['ID', 'NAME', 'DATE_ACTIVE_FROM', 'DATE_ACTIVE_TO']
);

5.8 Сортировка в произвольном порядке ID (≥ 18.6.700)

$ids = [115, 120, 117, 109, 128];

$res = CIBlockElement::GetList(
    ['ID' => $ids], // порядок как в массиве
    ['IBLOCK_ID' => 5, 'ID' => $ids],
    false,
    false,
    ['ID', 'NAME']
);

5.9 Постраничка с смещением (nOffset, ≥ 21.700.100)

$res = CIBlockElement::GetList(
    ['ID' => 'ASC'],
    ['IBLOCK_ID' => 2],
    false,
    ['nTopCount' => 5, 'nOffset' => 1000],
    ['ID', 'NAME']
);

5.10 Элементы с непустым значением множественного списка

$filter = [
    [
        'ID' => CIBlockElement::SubQuery(
            'ID',
            [
                'IBLOCK_ID'            => $iblockId,
                '!=PROPERTY_BRAND' => false,
            ]
        ),
    ],
];

$res = CIBlockElement::GetList([], $filter);

5.11 Поиск по SEARCHABLE_CONTENT

$arSelect = ['ID', 'NAME', 'DETAIL_PAGE_URL', 'PREVIEW_PICTURE'];
$arFilter = [
    'IBLOCK_ID'         => $iblockId,
    'ACTIVE_DATE'       => 'Y',
    'ACTIVE'            => 'Y',
    '%SEARCHABLE_CONTENT' => trim($_REQUEST['q']),
];
$res = CIBlockElement::GetList([], $arFilter, false, ['nPageSize' => 50], $arSelect);

5.12 Диапазон дат «с до»

$dateFrom = '12.09.2014';
$dateTo   = '18.09.2014';

$res = CIBlockElement::GetList(
    ['ID' => 'DESC'],
    [
        '>=DATE_CREATE' => $dateFrom,
        '<=DATE_CREATE' => $dateTo . ' 23:59:59',
    ]
);

5.13 Получить элементы отдела «Одежда» и подразделов

$arFilter = [
    'SECTION_CODE'      => 'clothes',
    'INCLUDE_SUBSECTIONS'=> 'Y',
    'ACTIVE'            => 'Y',
];

$res = CIBlockElement::GetList(['SORT' => 'ASC'], $arFilter);

5.14 Выбрать товары с остатков на складе 2 > 0

$arFilter = [
    'IBLOCK_ID'                 => $iblockId,
    '>CATALOG_STORE_AMOUNT_2'   => 0,
];

$arSelect = ['ID', 'NAME', 'CATALOG_QUANTITY'];
$res = CIBlockElement::GetList([], $arFilter, false, false, $arSelect);

5.15 D7-эквивалент (рекомендуемый для новых проектов)

use Bitrix\Iblock\Elements\ElementProductTable;

$result = ElementProductTable::getList([
    'select' => ['ID', 'NAME'],
    'filter' => ['=IBLOCK_ID' => $iblockId, '=ACTIVE' => 'Y'],
    'order'  => ['SORT' => 'ASC'],
    'limit'  => 50,
]);

while ($row = $result->fetch()) {
    // ...
}

6. Типичные ошибки и их решения

Симптом Причина Как исправить
Дубли элементов при сортировке по мультисвойству Свойство хранится в общей таблице Перевести инфоблок на отдельную таблицу или убирать свойство из arSelect
«Fatal error: Call to a member function GetNextElement() on bool» GetList() вернул false (пустой фильтр или ошибка) Проверять $res instanceof CDBResult
Навигация выдаёт 500 Используете nElementID без поля ID в arSelect Добавьте ID и явную сортировку

7. Вывод

CIBlockElement::GetList() остаётся фундаментом большинства компонентов и скриптов на 1С-Битрикс. Зная нюансы фильтрации, сортировки и оптимизации, вы сможете:

  • строить любые витрины каталога без «избыточных» запросов;
  • разделять логику на постраничку и групповые статистики;
  • мигрировать на D7-ORM постепенно, не ломая существующий функционал.

Берите примеры из статьи, адаптируйте к своим инфоблокам и проверяйте профилировщиком (/bitrix/admin/perfmon_table.php). Так вы добьётесь не только корректного, но и быстрого кода.

Удачной разработки!

Теги:  CIBlockElement::GetList(), API инфоблоков, фильтрация, сортировка, постраничка, D7-ORM, оптимизация производительности

Стоимость услуг по разработке и сопровождению сайтов на 1C-Битрикс

Разработка корпоративного сайта

от 7 дней

от 40 000 рублей

Разработка сайта без системы оплаты заказов через корзину

* стоимость зависит от наличия верстки, использования готового решения и т.д.

Модули и компоненты для «1С-Битрикс»

оценка производится на основе предоставленного Технического Задания

от 20 000 рублей
Разработка дополнительных модулей для 1С-Битрикс, расширение функционала, внедрение любых решений, требующихся для выполнения ваших бизнес-задач.

* стоимость зависит от конкретной задачи, ее объема и сложности выполняемых работ.

Перенос сайтов на «1С-Битрикс»

сайты на платформе «1С-Битрикс» — это удобство, надежность и высокая посещаемость

от 12 000 рублей
Перенос сайтов с любых CMS и статичных страниц на платформу «1С-Битрикс», с учетом дизайна, верстки и урл-адресов. С сохранением всей информации и структуры сайта.

* зависит от объема выполняемых работ.