Cron-импорт пишет в лог "false", а в каталоге пусто. На практике это частая проблема: Add вызван как статический метод, модуль iblock не подключен, в PROPERTY_VALUES для списка передали "Красный" вместо ID enum. Контракт Add простой: объект CIBlockElement, IBLOCK_ID + NAME, правильные форматы свойств, LAST_ERROR при false. Ниже - минимальный пример, PROPERTY_VALUES по типам, OnBeforeIBlockElementAdd и чек-лист отладки.
CIBlockElement::Add - нестатический метод класса CIBlockElement модуля iblock в 1С-Битрикс: Управление сайтом; добавляет новый элемент в инфоблок по массиву полей (обязательны IBLOCK_ID и NAME). Свойства передаются в ключе PROPERTY_VALUES; до записи вызывается OnBeforeIBlockElementAdd (отмена через ThrowException и return false), после - OnAfterIBlockElementAdd. При ошибке возвращает false, текст - в LAST_ERROR. Сегодня: подключите iblock, создайте $el = new CIBlockElement, передайте enum ID в списках, проверьте числовой ID > 0.
Речь про 1С-Битрикс: Управление сайтом, не про Bitrix24 CRM. Элемент инфоблока - товар, новость, услуга в каталоге CMS. Инфоблок еще не создан - гайд по созданию инфоблока. Уже есть карточка и нужно изменить поля - CIBlockElement::Update, не дублируйте Add.
Разберите, когда нужен программный Add, а не админка
CIBlockElement::Add - PHP-метод для создания новой записи в инфоблоке: cron, миграция, форма на сайте через свой код, обмен с 1С. В админке то же действие - кнопка "Добавить элемент", но руками это не масштабируется.
| Ситуация | Админка | CIBlockElement::Add |
|---|---|---|
| Одна новость | Быстрее | Избыточно |
| Импорт 3000 SKU | Нереально | Обязателен API |
| Форма отзывов на сайте | Нет публичного UI | Add или компонент |
| Дубликат CODE | Видно в форме | false + LAST_ERROR |
Делайте: автоматизируйте массовое создание. Не делайте: Add для разовой карточки, если админка справится.
Что такое CIBlockElement::Add и когда он нужен
CIBlockElement::Add создает элемент и возвращает числовой ID при успехе. Обязательны IBLOCK_ID (номер инфоблока) и NAME (название). Остальные поля - ACTIVE, CODE, разделы, картинки, свойства - опциональны, но PROPERTY_VALUES при создании задает начальные значения свойств одним массивом.
Нужен Add, когда записи появляются из кода без ручного ввода. Не нужен, если контент-менеджер ведет каталог вручную или вы только правите существующие ID через Update.
Выполните минимальный Add: модуль, поля и проверка ID
- Модуль:
Loader::includeModule('iblock')илиCModule::IncludeModule('iblock'). - Объект:
$el = new CIBlockElement;- не статический вызов и неnew CIBlockElement::Add. - Поля: IBLOCK_ID, NAME, при необходимости ACTIVE = Y.
- Вызов и проверка:
$id = $el->Add($arFields);— если $id число > 0, элемент создан; при false читайте$el->LAST_ERRORили$el->getLastError()(с версии 24.100.0).
<?php
use Bitrix\Main\Loader;
Loader::includeModule('iblock');
$el = new CIBlockElement;
$arFields = [
'IBLOCK_ID' => 7,
'NAME' => 'Товар из импорта',
'ACTIVE' => 'Y',
];
$id = $el->Add($arFields);
if (!$id) {
echo $el->LAST_ERROR;
}
В реальном проекте типичная ошибка: Add без includeModule или new CIBlockElement::Add(...) — белый экран вместо LAST_ERROR, каталог не работает.
Делайте: тест на dev. Не делайте: импорт на прод без проверки ID.
Заполните PROPERTY_VALUES при создании по типам свойств
Ключ PROPERTY_VALUES в $arFields - массив "код или ID свойства → значение". При Add не действует ловушка полной перезаписи как при Update: вы задаете только то, что нужно сразу. Но формат значения зависит от типа свойства.
| Тип свойства | Что передать в PROPERTY_VALUES | Типичная ошибка |
|---|---|---|
| Строка / число | Текст или число: 'ARTICLE' => 'SKU-001' |
Пустой NAME в полях, не в свойствах |
| Список (select) | ID enum, не текст VALUE | "Красный" вместо 42 |
| Файл | CFile::MakeFileArray($path) |
Путь без MakeFileArray |
| Множественное | Массив значений | Одно значение без массива |
| Привязка к элементу | ID связанного элемента | Неверный IBLOCK_ID связи |
$arFields['PROPERTY_VALUES'] = [
'ARTICLE' => 'SKU-100',
'COLOR' => 15, // ID enum из CIBlockPropertyEnum::GetList
'DOCS' => CFile::MakeFileArray($_SERVER['DOCUMENT_ROOT'].'/upload/file.pdf'),
];
$id = $el->Add($arFields);
ID enum - через CIBlockPropertyEnum. Текст "Красный" оставит список пустым.
Делайте: для списков ID. Не делайте: копировать форматы из Update без проверки.
Привяжите элемент к разделам, датам и картинкам
IBLOCK_SECTION_ID - один основной раздел (число). IBLOCK_SECTION - массив ID для нескольких разделов. CODE - символьный код; дубликат в одном инфоблоке даст false и текст в LAST_ERROR.
Даты ACTIVE_FROM и ACTIVE_TO - в формате сайта (обычно dd.mm.yyyy hh:ii:ss). PREVIEW_PICTURE и DETAIL_PICTURE - через CFile::MakeFileArray, как файловые свойства.
$arFields['IBLOCK_SECTION_ID'] = 12;
$arFields['CODE'] = 'sku-100';
$arFields['ACTIVE_FROM'] = '28.07.2026 10:00:00';
$arFields['PREVIEW_PICTURE'] = CFile::MakeFileArray($imgPath);
Делайте: уникальный CODE при автогенерации из внешнего ID. Не делайте: путать IBLOCK_SECTION и IBLOCK_SECTION_ID в одном импорте без чтения справки.
Настройте OnBeforeIBlockElementAdd и OnAfterIBlockElementAdd
OnBeforeIBlockElementAdd срабатывает внутри Add до записи в БД. Массив $arFields по ссылке - можно нормализовать CODE, проверить дубликаты, отменить создание. Отмена: $APPLICATION->ThrowException('текст'); return false; в обработчике. ID элемента еще нет - в отличие от OnAfter.
OnAfterIBlockElementAdd - после успешного Add, ID известен. Симметрия Update - OnBeforeIBlockElementUpdate. Регистрация - гайд по обработчикам.
// OnBefore: отмена дубликата CODE
function myOnBeforeAdd(&$arFields) {
if (empty($arFields['CODE'])) { return true; }
$rs = CIBlockElement::GetList([], [
'IBLOCK_ID' => $arFields['IBLOCK_ID'],
'CODE' => $arFields['CODE'],
]);
if ($rs->Fetch()) {
global $APPLICATION;
$APPLICATION->ThrowException('Дубликат CODE');
return false;
}
return true;
}
Делайте: валидацию до Add в OnBefore. Не делайте: тяжелую логику в OnAfter без проверки, что Add не отменен.
Выберите Add, D7 ORM или компонент iblock.element.add
Decision tree:
Массовый импорт / cron? → CIBlockElement::Add.
Публичная форма на сайте? → компонент bitrix:iblock.element.add.
ElementTable::add? → заблокирован в D7, канон - Add.
Инфоблок 2.0 с ORM-классом? → сгенерированный ElementXxxTable::add, не путать с заблокированным ElementTable.
ElementTable::add заблокирован - канон Add. Массовый импорт: $el->Add($arFields, false, false) - bUpdateSearch off; переиндексация после цикла.
Делайте: Add для бэкенда и cron. Не делайте: путать CMS Add с crm.item.add из Bitrix24 REST.
Проверьте чек-лист, если элемент не создается
- false без текста: includeModule('iblock'), объект new CIBlockElement, не статический вызов.
- LAST_ERROR: дубль CODE, неверный IBLOCK_ID, обязательное свойство в OnBefore.
- Свойство пустое: список - ID enum; файл - MakeFileArray.
- Обработчик и админка: grep OnBeforeIBlockElementAdd в local/php_interface; return false без ThrowException. Проверка: фильтр по IBLOCK_ID и ID из Add, GetList в коде.
Схема импорта: includeModule → $arFields + PROPERTY_VALUES → Add → проверка ID → лог LAST_ERROR → GetList.
Аудит обмена - обсудите проект, кейсы - портфолио. Делайте: лог LAST_ERROR с SKU. Не делайте: игнорировать false в cron.
Автор: Максим Мольков, разработчик 1С-Битрикс.
Источники: CIBlockElement::Add, OnBeforeIBlockElementAdd, OnAfterIBlockElementAdd, практика внедрений CMS.
Частые вопросы
Как создать элемент инфоблока программно в Битрикс?
Loader::includeModule('iblock'), $el = new CIBlockElement, $arFields с IBLOCK_ID и NAME, $id = $el->Add($arFields). Успех - числовой ID > 0. При false читайте $el->LAST_ERROR. Свойства - в PROPERTY_VALUES при том же вызове Add.
Что передать в PROPERTY_VALUES при CIBlockElement::Add?
Массив: код свойства → значение. Строка и число - как есть. Список - ID enum, не текст. Файл - CFile::MakeFileArray. Множественное - массив значений. Привязка к элементу - ID связанной записи.
Чем Add отличается от Update в инфоблоке?
Add создает новую запису и возвращает новый ID. Update требует ELEMENT_ID существующего элемента. Ловушка полного PROPERTY_VALUES при Update - в гайде по CIBlockElement::Update.
Как отменить создание элемента через OnBeforeIBlockElementAdd?
В обработчике OnBeforeIBlockElementAdd: $APPLICATION->ThrowException('причина'); return false;. Элемент не создастся, текст попадет в LAST_ERROR. ID еще не существует - в отличие от OnAfterIBlockElementAdd.
Почему CIBlockElement::Add возвращает false?
Частые причины: не подключен модуль iblock, неверный IBLOCK_ID, дубль CODE, отмена в OnBeforeIBlockElementAdd, неверный формат PROPERTY_VALUES для списка. Текст - в $el->LAST_ERROR или getLastError().
Можно ли использовать ElementTable::add в D7?
ElementTable::add в официальной D7-справке заблокирован. Для legacy инфоблоков используйте CIBlockElement::Add. Для инфоблоков 2.0 с ORM-классом - сгенерированный ElementXxxTable, не путать с ElementTable.
Add или компонент bitrix:iblock.element.add?
CIBlockElement::Add - для импорта, cron и бэкенда без UI. Компонент iblock.element.add - готовая публичная форма на сайте с шаблоном. API и компонент решают разные задачи, не заменяют друг друга в импорте.