Работа со свойствами элементов инфоблока в 1С-Битрикс - получение, обновление и удаление

Работа со свойствами инфоблока в 1С-Битрикс — одна из самых частых задач при разработке корпоративных порталов, интернет-магазинов и других веб-проектов. В этой статье мы разберём, как получать, обновлять и удалять значения свойств элементов, а также объясним ключевые моменты для успешной работы (включая классический API через CIBlockElement и краткие примеры D7 — ORM Bitrix Framework). Особое внимание уделим отличиям в хранении свойств (отдельная таблица b_iblock_element_prop_sXX vs общая b_iblock_element_property), а также различиям между методами обновления свойств.

Руководство по работе со свойствами элементов инфоблока в 1С-Битрикс

1. Введение в свойства инфоблока

Свойства инфоблока — это дополнительные поля, которые позволяют хранить расширенную информацию об элементах (например, артикул, цвет, размер и т.д.). В отличие от стандартных полей (название, дата создания, автор и т.п.), свойства настраиваются администратором системы и могут иметь различные типы:

  • Строка (String)
  • Число (Number)
  • Список (List)
  • Файл (File)
  • Привязка к элементам, разделам, пользователям и т.д.
  • И многие другие.

Свойства могут быть одиночными или множественными (хранить несколько значений). При работе с ними важно учитывать тип каждого свойства, особенно если оно множественное, чтобы правильно читать и перезаписывать данные.


2. Способы обращения к свойствам

2.1 Подключение модуля «iblock»

Перед любыми операциями с инфоблоками необходимо подключить модуль:

use Bitrix\Main\Loader;

Loader::includeModule('iblock');

Без этого методы CIBlockElement, CIBlockProperty и т.д. будут недоступны.

2.2 Классические методы CIBlockElement и CIBlockProperty

Наиболее распространённый и гибкий способ — использовать методы классов ядра 1С-Битрикс:

  • CIBlockElement для получения, добавления, обновления и удаления элементов, а также их свойств.
  • CIBlockProperty для управления свойствами на уровне инфоблока (создание/удаление, изменение параметров и т.д.).

2.3 Компоненты высокого уровня

Стандартные компоненты (bitrix:catalog, bitrix:news и др.) получают и выводят свойства автоматически на основе настроек. Однако для тонкой настройки или автоматизации придётся обращаться к API или дополнять/переопределять шаблоны.

2.4 D7 ORM (Bitrix Framework)

Bitrix Framework предлагает объектно-ориентированный подход к работе с данными (D7). Для инфоблоков в современных версиях ядра (и при условии генерации ORM-классов) могут появляться классы вида \Bitrix\Iblock\Elements\Element[СимвольныйКод]Table, позволяющие:

  • Получать элементы с нужными свойствами (через PROPERTY_XXX поля).
  • Обновлять и удалять значения.

Важно понимать, что не во всех проектах эти ORM-классы доступны из коробки. Они создаются генератором кода (или вручную). Если у вас появляется ошибка Class "Bitrix\Iblock\Elements\ElementCatalogTable" not found, это означает, что либо класс действительно не был сгенерирован, либо у вас более старая версия ядра.


3. Получение свойств элемента

3.1 Где хранятся свойства (отдельная vs общая таблица)

  • Отдельная таблица (b_iblock_element_prop_sXX): включается в настройках инфоблока («Хранить значения свойств в отдельной таблице»). В таком случае GetNextElement()->GetProperties() обычно корректно возвращает все данные.
  • Общая таблица (b_iblock_element_property): часто используется по умолчанию или для «небольших» инфоблоков. При таком хранении бывают случаи, когда GetNextElement()->GetProperties() возвращает пустые результаты (в частности, при определённых настройках свойств или в устаревших версиях).

3.2 Универсальный способ через CIBlockElement::GetProperty

Чтобы не «угадывать», где именно хранятся свойства, надёжнее всего использовать метод

$resProps = CIBlockElement::GetProperty($IBLOCK_ID, $ELEMENT_ID, ..., $filter);

Он вернёт все значения свойства(в), независимо от типа хранения. Пример:

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

$iblockId  = 2;
$elementId = 456;

$propsRes = CIBlockElement::GetProperty(
    $iblockId,
    $elementId,
    ["sort" => "asc"], // можно сортировать
    ["ACTIVE" => "Y"]  // можно фильтровать, напр. по коду свойства
);

$allProps = [];
while($arProp = $propsRes->Fetch())
{
    // Каждый вызов Fetch() возвращает одно значение,
    // даже если свойство множественное.
    $propCode = $arProp["CODE"];
    if(!isset($allProps[$propCode])) {
        $allProps[$propCode] = [];
    }
    $allProps[$propCode][] = $arProp["VALUE"];
}

echo "<pre>";
print_r($allProps);
echo "</pre>";

Данный метод всегда получает реальные данные свойств, вне зависимости от способа хранения. Если свойство множественное, вернётся несколько записей. Если одиночное — одна. Это универсальный и надёжный подход.

3.3 Примеры с GetNextElement() / GetNext()

  • GetNextElement() + $ob->GetProperties(): работает в большинстве случаев, но может возвращать пустые массивы, если инфоблок не хранит данные в отдельной таблице или в ряде других случаев (особенно старые версии Битрикс).
$arSelect = ["ID", "NAME", "CODE", "PROPERTY_*"];
$arFilter = ["IBLOCK_ID" => $iblockId, "ID" => $elementId, "ACTIVE" => "Y"];

$res = CIBlockElement::GetList([], $arFilter, false, false, $arSelect);

if($ob = $res->GetNextElement())
{
    $arFields = $ob->GetFields();
    // В инфоблоках с отдельной таблицей свойств это обычно сработает:
    $arProps = $ob->GetProperties();

    print_r($arFields);
    print_r($arProps); // Может быть пусто, если общая таблица и особые настройки.
}
  • GetNext() с PROPERTY_*: даёт поля вида PROPERTY_КОД_СВОЙСТВА_VALUE напрямую в массиве $arItem. В некоторых случаях (особенно в общих таблицах) это работает, но нередко встречаются ситуации, когда данные не возвращаются полностью.
$arSelect = ["ID","NAME","PROPERTY_BRAND","PROPERTY_PRICE"];
$res = CIBlockElement::GetList([], ["IBLOCK_ID"=>$iblockId], false, false, $arSelect);
if($arItem = $res->GetNext())
{
    // Могут появиться поля $arItem["PROPERTY_BRAND_VALUE"], $arItem["PROPERTY_PRICE_VALUE"]
    echo $arItem["PROPERTY_BRAND_VALUE"];
    echo $arItem["PROPERTY_PRICE_VALUE"];
}

Важное замечание: Поведение GetNext() и GetNextElement() может отличаться в разных версиях Битрикс и с разными настройками инфоблока. Если вы уверены, что инфоблок хранит свойства в отдельной таблице, GetNextElement()->GetProperties() обычно оптимально. Если есть проблемы (пусто при выборке), переходите на CIBlockElement::GetProperty() — это самый «низкоуровневый», но стабильный метод.

3.4 Пример с D7 (если доступен класс)

В современных проектах (и при сгенерированных ORM-классах) можно использовать D7:

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

// Это примерный класс, может отличаться
use Bitrix\Iblock\Elements\ElementCatalogTable;

$res = ElementCatalogTable::getList([
    'select' => [
        'ID',
        'NAME',
        'BRAND',  // свойства
        'PRICE'
    ],
    'filter' => [
        '=ID' => 123,
        '=ACTIVE' => 'Y'
    ],
    'limit' => 1
]);

if ($arItem = $res->fetch()) {
    echo 'ID: ' . $arItem['ID'] . PHP_EOL;
    echo 'Название: ' . $arItem['NAME'] . PHP_EOL;
    echo 'Бренд: ' . $arItem['BRAND'] . PHP_EOL;
    echo 'Цена: ' . $arItem['PRICE'] . PHP_EOL;
}

Для работы с элементами используется класс \Bitrix\Iblock\Elements\ElementXXXXXTable, где XXXXX - Символьный код API. Для инфоблока на примере выше это будет класс \Bitrix\Iblock\Elements\ElementCatalogTable.

Если получаете ошибку Class "Bitrix\Iblock\Elements\ElementCatalogTable" not found, значит либо класс не сгенерирован, либо более старая версия ядра, либо нет привязки к символьному коду `catalog`.


4. Обновление значений свойств

В классическом API 1С-Битрикс есть несколько способов изменения свойств элемента. Однако нужно понимать, какие из них требуют полный список свойств, а какие меняют только указанные.

4.1 CIBlockElement::SetPropertyValues($ELEMENT_ID, $IBLOCK_ID, $PROPERTY_VALUES, $PROPERTY_CODE = false)

  1. Если передан четвертый параметр $PROPERTY_CODE (код/ID одного свойства), обновляется только это свойство; остальные не трогаются.
  2. Если четвёртый параметр не передан, ожидается, что в третьем параметре $PROPERTY_VALUES передадите все свойства данного элемента. Все неуказанные свойства будут сброшены.

Примеры:

// Обновляем только одно свойство PRICE (остальные не тронет)
CIBlockElement::SetPropertyValues($elementId, $iblockId, 999, "PRICE");

// Обновляем все свойства: те, что не указаны, будут очищены!
CIBlockElement::SetPropertyValues($elementId, $iblockId, [
    "PRICE" => 999,
    "ARTNUMBER" => "ABC-123"
    // Если было свойство BRAND, но здесь не указали, оно сотрётся
]);

4.2 CIBlockElement::SetPropertyValuesEx($ELEMENT_ID, $IBLOCK_ID, $PROPERTY_VALUES)

Этот метод точечно обновляет только перечисленные свойства, не затрагивая остальные. Иными словами, если вы не указали BRAND, но он уже существует, то BRAND останется прежним:

CIBlockElement::SetPropertyValuesEx($elementId, $iblockId, [
    "PRICE" => 999,
    "ARTNUMBER" => "ABC-123"
]);
// BRAND, PHOTOS и другие свойства не изменятся

4.3 CIBlockElement::Update($ELEMENT_ID, $arFields)

Нередко встречается код:

$el = new CIBlockElement();
$res = $el->Update($elementId, [
    "NAME" => "Новое имя",
    "PROPERTY_VALUES" => [
        "PRICE" => 999,
        "ARTNUMBER" => "A-5678"
    ]
]);

Важно: передача PROPERTY_VALUES таким образом, по логике ядра, зачастую работает как полный SetPropertyValues без указания $PROPERTY_CODE, т.е. требует полного списка. Это значит, что неуказанные свойства могут быть очищены. Поведение на разных версиях Битрикс может отличаться, но в большинстве случаев это не «точечное» обновление.

Чтобы обновлять свойства «точечно» и не сбрасывать остальные, надёжнее вызывать SetPropertyValuesEx, либо вызывать SetPropertyValues с конкретным $PROPERTY_CODE.

4.4 Обновление через D7 (если класс доступен)

Синтаксис похож:

// Принимаем, что класс ElementCatalogTable у вас есть
ElementCatalogTable::update($elementId, [
    'NAME' => 'Новое название',
    'PROPERTY_VALUES' => [
        'PRICE' => 999
        // Остальные свойства могут обнулиться,
        // если в конкретной реализации D7 так устроено.
    ]
]);

Поведение здесь зависит от реализации конкретного D7-класса. Некоторые конфигурации «точечно» обновляют свойства, другие — могут сбрасывать неуказанные. Уточняйте в документации или тестируйте на тестовом элементе.


5. Удаление значений свойств

В Битрикс нет отдельного метода «Удалить свойство». Удаление — это запись пустого / false.

5.1 Сброс одиночного свойства

CIBlockElement::SetPropertyValues($elementId, $iblockId, false, "PRICE");

Или через SetPropertyValuesEx:

CIBlockElement::SetPropertyValuesEx($elementId, $iblockId, [
    "PRICE" => false
]);

5.2 Удаление одного значения множественного свойства

Если свойство множественное (например, несколько фото):

  1. Сначала получаем текущее содержимое (через GetProperty или $res->GetNext()).
  2. Исключаем ненужное значение.
  3. Устанавливаем обновлённый массив.
$currentPhotos = []; // Получаем массив текущих значений

// Удалим фото с ID=126
$newPhotos = [];
foreach($currentPhotos as $photoId) {
    if($photoId != 126) {
        $newPhotos[] = $photoId;
    }
}

// Записываем
CIBlockElement::SetPropertyValues($elementId, $iblockId, $newPhotos, "PHOTOS");

5.3 Удаление через D7

Если реализация ORM предполагает «точечный» подход, можно попробовать:

ElementCatalogTable::update($elementId, [
    'PROPERTY_VALUES' => [
        'PHOTOS' => []
    ]
]);

Но, повторимся, конкретное поведение может отличаться. Всегда проверяйте на тестовом элементе, чтобы убедиться, что не удаляете другие свойства.


6. Полезные советы и лучшие практики

  1. Всегда учитывайте, как хранятся свойства
    • Отдельная таблица (GetNextElement()->GetProperties() работает хорошо).
    • Общая таблица (при сложностях используйте CIBlockElement::GetProperty).
  2. Кэширование При массовых операциях (например, выборка сотен элементов) используйте механизмы кэширования.
  3. Правильные типы данных Если свойство числовое, передавайте число. Если строковое — строку.
  4. Множественные свойства Аккуратно объединяйте и перезаписывайте значения, чтобы не потерять уже существующие.
  5. Проверка прав Перед любыми операциями обновления/удаления убедитесь, что у пользователя есть соответствующие права.
  6. Отличия методов
    • SetPropertyValues с четвёртым параметром ($PROPERTY_CODE) меняет одно свойство точечно. Без четвёртого — требует полный список свойств.
    • SetPropertyValuesEx — точечное обновление нескольких свойств.
    • Update(..., ["PROPERTY_VALUES" => [...]]) в большинстве случаев перезаписывает все свойства, т.е. может «очистить» неуказанные.
  7. D7-классы
    • Есть не во всех проектах.
    • Иногда тоже могут очищать неуказанные свойства.

7. Заключение

Работа со свойствами инфоблоков в 1С-Битрикс — ключевая часть разработки. Чтобы избежать путаницы и потери данных:

  • Проверяйте, где инфоблок хранит свойства (общая или отдельная таблица). Если возникают проблемы с выборкой, используйте CIBlockElement::GetProperty.
  • Не путайте методы «точечного» обновления (SetPropertyValuesEx, SetPropertyValues + $PROPERTY_CODE) и методы полной перезаписи (SetPropertyValues без четвёртого параметра, Update с PROPERTY_VALUES).
  • Внимательно тестируйте, если используете D7. Не все версии одинаково обрабатывают «неуказанные» свойства.

При грамотном подходе вам будет удобно получать, обновлять и удалять свойства без неприятных сюрпризов и обнуления данных.

Теги:  руководство

Интернет-магазин от 120 000 руб., срок от 4 недель

Платформа для продажи товаров или услуг. Включает интерактивные формы обратной связи в каждой карточке товара, а также множество статичных и динамичных разделов.

Корпоративный сайт от 60 000 руб., срок от 3 недель

Готовый информационный ресурс, включающий лицензию на 1С-Битрикс «Стандарт», технологию «Композитный сайт».

Лендинг от 25 000 руб., срок от 2 недель

Компактный сайт, идеально подходящий для старта. На одной странице можно представить ключевые преимущества вашей компании и разместить форму для обратной связи.