Теоретический разбор, практические сценарии и решения типовых ошибок с рабочими примерами D7-ORM

1. Зачем он нужен
Поле «Символьный код API» задаёт внутренний идентификатор, по которому ядро D7 автоматически генерирует ORM-классы для элементов, разделов и свойств без явного указания IBLOCK_ID
.
Достаточно заполнить поле один раз — и у вас появляются компактные, типобезопасные классы:
\Bitrix\Iblock\Elements\Element<API_CODE>Table // элементы
\Bitrix\Iblock\Sections\Section<API_CODE>Table // разделы
\Bitrix\Iblock\Property<API_CODE><PROP_CODE>Table // каждое одиночное свойство
Для инфоблока c API_CODE = Catalog
и свойства PRICE
ядро создаст, например:
\Bitrix\Iblock\Elements\ElementCatalogTable
\Bitrix\Iblock\Sections\SectionCatalogTable
\Bitrix\Iblock\PropertyCatalogPriceTable
2. Как задать API_CODE
- Админ-панель → Контент → Инфоблоки → нужный инфоблок → Настройки.
- В поле «Символьный код API» введите латиницу без пробелов (A-Z / a-z / 0-9, 1–50 символов; первый — обязательно буква).
⚠️ Изменять уже используемый код крайне нежелательно: придётся переименовывать классы по всему проекту.
3. Обязательное подключение модуля
Перед любым обращением к ORM-классам подключайте модуль:
use Bitrix\Main\Loader;
Loader::includeModule('iblock');
Без этого Bitrix не зарегистрирует сущности и выбросит исключение.
4. Автогенерация классов
После сохранения API_CODE
движок компилирует PHP-классы в runtime-кэш (папка /bitrix/cache
). При первом обращении Bitrix подгрузит схему и вернет Entity-объект.
5. Базовые операции с элементами
5.1 Выборка
use Bitrix\Iblock\Elements\ElementCatalogTable;
$items = ElementCatalogTable::getList([
'select' => [
'ID',
'NAME',
// одиночное числовое свойство
'PRICE_VALUE' => 'PRICE',
// перечислимое свойство (берём текстовое значение, а не NAME связанной сущности)
'STATUS_VALUE' => 'STATUS.VALUE',
],
'filter' => [
'=ACTIVE' => 'Y',
// сравнение безопаснее делать со строкой
'>PRICE' => '1000',
],
'order' => ['PRICE_VALUE' => 'ASC'],
'cache' => ['ttl' => 3600],
])->fetchAll();
5.2 Добавление элемента
$element = ElementCatalogTable::createObject();
$element
->setName('Новый товар')
->setActive(true)
->setPrice('1999.90') // строкой - избегаем ошибок float
->setStatus(3) // ID значения списка
->save();
5.3 Обновление
ElementCatalogTable::update($itemId, [
'ACTIVE' => 'N',
'PRICE' => '1499',
]);
5.4 Удаление
ElementCatalogTable::delete($itemId);
6. Работа с разделами
use Bitrix\Iblock\Sections\SectionCatalogTable;
$sections = SectionCatalogTable::getList([
'select' => ['ID', 'NAME', 'DEPTH_LEVEL'],
'order' => ['LEFT_MARGIN' => 'ASC'],
])->fetchAll();
Создание раздела:
$section = SectionCatalogTable::createObject();
$section
->setName('Новая категория')
->setCode('new-category')
->setActive(true)
->save();
7. Свойства как отдельные сущности
Для одиночных числовых, строковых и перечислимых свойств ядро создаёт классы-таблицы (для множественных, файлов и привязок — нет).
use Bitrix\Iblock\PropertyCatalogPriceTable;
// все цены > 5000
$prices = PropertyCatalogPriceTable::getList([
'select' => ['ELEMENT_ID', 'VALUE'],
'filter' => ['>VALUE' => '5000'],
])->fetchAll();
8. Динамическая компиляция, если API_CODE
неизвестен
use Bitrix\Iblock\Iblock;
// регистр ДОЛЖЕН совпадать с API_CODE !
$iblock = Iblock::loadByCode('Catalog'); // или Iblock::wakeUp($id)
$dataClass = $iblock->getEntityDataClass(); // вернёт ElementCatalogTable
$rows = $dataClass::getList([
'select' => ['ID', 'NAME'],
])->fetchAll();
9. Миграция старого проекта
- В админке заполните
API_CODE
всем существующим инфоблокам. - В коде замените ручные
IBLOCK_ID
наElement<Code>Table
иSection<Code>Table
. - Там, где код модуля получает ID инфоблока на лету, оставьте универсальный
Iblock::wakeUp()
— он продолжит работать.
10. Практические рекомендации
Совет | Пояснение |
---|---|
Задавайте API_CODE до выхода в прод |
Избавит от массового рефакторинга позже. |
Пишите код в CamelCase | Так же будут называться классы; читаемость выше. |
Кэшируйте тяжёлые выборки | Параметр cache в getList() работает с Managed Cache. |
Не смешивайте старое API | Используйте либо CIBlockElement , либо D7-ORM, но не оба вместе. |
Проверяйте права через ORM | ElementCatalogTable::query()->withPermissions() учитывает ACL-ы. |
Помните о регистре | loadByCode('Catalog') не равно loadByCode('catalog') . |
11. Заключение
Символьный код API — одно маленькое поле, которое экономит сотни строк: убирает вечные фильтры по IBLOCK_ID
, даёт лаконичные классы, ускоряет автоподсказки IDE и делает проект чище.
Заполняйте его правильно, подключайте Loader::includeModule('iblock');
, придерживайтесь единого стиля — и работать с данными в 1С-Битрикс станет куда удобнее.