Для чтения одного свойства одного элемента инфоблока в API есть
несколько путей — и не все они одинаково эффективны. Разберём
CIBlockElement::GetProperty в сравнении с
GetList, и когда использование каждого из них
оправдано.
CIBlockElement::GetProperty
<?php
$result = CIBlockElement::GetProperty(
$iblockId, $elementId, ['sort' => 'asc'], ['CODE' => 'COLOR']
);
while ($property = $result->Fetch()) {
echo $property['VALUE'];
}
Этот метод специализирован именно на получении значений свойств конкретного элемента — компактный синтаксис для случая, когда элемент уже известен и нужны именно его свойства, без остальных полей самого элемента (названия, даты создания и так далее).
GetList с фильтром по одному элементу
<?php
$element = CIBlockElement::GetList(
[], ['ID' => $elementId], false, false, ['ID', 'PROPERTY_COLOR']
)->Fetch();
echo $element['PROPERTY_COLOR_VALUE'];
GetList с фильтром по ID одного элемента — более
универсальный способ, дающий доступ и к обычным полям элемента,
и к свойствам одновременно, за один вызов. Если нужны и название
элемента, и его свойства сразу, GetList экономит
один из двух запросов по сравнению с раздельным вызовом
GetByID и GetProperty.
Нужна помощь с Битрикс?
Когда GetProperty оправдан
Если нужны только свойства, а не остальные поля элемента,
и особенно если нужны все свойства элемента с их полным набором
метаданных (не только значение, но и код, название свойства,
тип) — GetProperty без явного перечисления кодов
свойств возвращает весь набор в удобной для перебора форме,
что менее удобно получить через GetList, ориентированный
на явно перечисленные в выборке поля.
Производительность на большом числе элементов
Оба метода в цикле по списку элементов создают проблему N+1
запросов — вызов на каждый элемент отдельно вместо одной общей
выборки. Для списков правильный подход — использовать
GetList сразу с фильтром по массиву ID элементов
и нужными свойствами в выборке, получая все данные одним запросом,
а не вызывать GetProperty или повторный
GetList в цикле по каждому элементу списка.
<?php
// эффективно: один запрос на весь список
$result = CIBlockElement::GetList(
[], ['IBLOCK_ID' => $iblockId, 'ID' => $elementIds], false, false,
['ID', 'PROPERTY_COLOR', 'PROPERTY_SIZE']
);
Множественные свойства через оба метода
Оба метода одинаково справляются с множественными свойствами —
GetProperty вернёт несколько строк результата
на одно множественное свойство с несколькими значениями,
GetList вернёт массив значений в поле с суффиксом
_VALUE. Разница в форме представления результата,
а не в принципиальной возможности работать с множественностью.
Фильтрация по значению конкретного свойства
<?php
$result = CIBlockElement::GetProperty(
$iblockId, $elementId, [], ['CODE' => 'COLOR', '!VALUE' => false]
);
GetProperty поддерживает собственный фильтр
по параметрам свойства, включая фильтрацию по значению —
для сценариев, где нужно найти конкретное значение свойства
среди множественных значений одного элемента, это удобнее, чем
получать весь массив через GetList и фильтровать
его вручную в PHP уже после выборки.
Частые ошибки
- GetProperty вызывается в цикле по списку элементов. Классическая проблема N+1 запросов там, где хватило бы одного GetList с фильтром по массиву ID.
- GetList используется, когда нужен только один параметр свойства. GetProperty компактнее для случая, когда элемент уже известен и нужны именно свойства.
- Ручная фильтрация массива значений в PHP вместо фильтра GetProperty. Дополнительная работа там, где сам метод уже поддерживает нужную фильтрацию.
Итог
GetProperty удобен для точечного получения свойств
одного уже известного элемента, особенно при работе с полным
набором метаданных свойств, тогда как GetList
эффективнее для получения элемента целиком (полей и свойств
одновременно) и обязателен для списков элементов, где важно
избежать проблемы N+1 запросов через единую выборку по массиву ID.
