Методы ORM Bitrix - Сергей Житников: Web-разработчик

Методы ORM Bitrix

Использовать Bitrix ORM не сложно. Работа ведется с таблицами, а не сущностями (как в старом ядре). Список таблиц БД Bitrix можно увидеть по ссылке

Как использовать ORM

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

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

Пример запроса в таблицу , содержащую элементы инфоблока:

$dbItems = \Bitrix\Iblock\ElementTable::getList([
    'order' => ['SORT' => 'ASC'], // сортировка
    'select' => ['ID', 'NAME', 'IBLOCK_ID', 'SORT', 'TAGS'], // выбираемые поля, без свойств. Свойства можно получать на старом ядре \CIBlockElement::getProperty
    'filter' => ['IBLOCK_ID' => 4,
                    'LOGIC' => 'OR', 
                    [
                        'ID' => 41,
                    ],
                    [
                        'ID' => 42, // Второе условие для "или"
                    ],
], // фильтр только по полям элемента, свойства (PROPERTY) использовать нельзя
    'group' => ['TAGS'], // группировка по полю, order должен быть пустой
    'limit' => 1000, // целое число, ограничение выбираемого кол-ва
    'offset' => 0, // целое число, указывающее номер первого столбца в результате
    'count_total' => 1, // дает возможность получить кол-во элементов через метод getCount()
    'runtime' => array(), // массив полей сущности, создающихся динамически
    'data_doubling' => false, // разрешает получение нескольких одинаковых записей
    'cache' => [ // Кеш запроса. Сброс можно сделать методом \Bitrix\Iblock\ElementTable::getEntity()->cleanCache();
        'ttl' => 3600, // Время жизни кеша
        'cache_joins' => true // Кешировать ли выборки с JOIN
    ],
]);

Что можно делать с $dbItems?

$dbItems->fetch(); // или $dbItems->fetchRaw() получение одной записи, можно перебрать в цикле while ($arItem = $dbItems->fetch())
$dbItems->fetchAll(); // получение всех записей
$dbItems->fetchCollection(); // получение всех записей в виде объектов (коллекций)
$dbItems->getCount(); // кол-во найденных записей без учета limit, доступно если при запросе было указано count_total = 1
$dbItems->getSelectedRowsCount(); // кол-во полученных записей с учетом limit

Другие методы:

checkFields(Result $result, $primary, array $data) // метод проверяет поля данных перед записью в БД.
getById($id) // получение элемента по ID
getByPrimary($primary, array $parameters = array()) // метод возвращает выборку по первичному ключу сущности и по опциональным параметрам \Bitrix\Main\Entity\DataManager::getList.
getConnectionName() // метод возвращает имя соединения для сущности. 12.0.9
getCount($filter = array(), array $cache = array()) // метод выполняет COUNT запрос к сущности и возвращает результат. 12.0.10
getEntity() // метод возвращает объект сущности.
getList(array $parameters = array()) // получение элементов, подробнее было выше
getMap() // метод возвращает описание карты сущностей. 12.0.7
getRow(array $parameters) // метод возвращает один столбец (или null) по параметрам для \Bitrix\Main\Entity\DataManager::getList.
getRowById($id) // метод возвращает один столбец (или null) по первичному ключу сущности. 14.0.0
getTableName() // метод возвращает имя таблицы БД для сущности. 12.0.7
query() // метод создаёт и возвращает объект запроса для сущности.
enableCrypto($field, $table = null, $mode = true) // метод устанавливает флаг поддержки шифрования для поля. 17.5.14
cryptoEnabled($field, $table = null) // метод возвращает true если шифрование разрешено для поля. 17.5.14
addMulti($rows, $ignoreEvents = false)
updateMulti($primaries, $data, $ignoreEvents = false)
// Следующий методы заблокированы у инфоблоков
add(array $data) // добавление элемента
delete($primary) // удаление элемента по ID
update($primary, array $data) // обновление элемента по ID

Альтернативный вариант получения данных

Альтернативный вариант получения данных с помощью Bitrix\Main\Entity\Query:

// Получение символьных кодов свойств с помощью ORM
use Bitrix\Iblock\PropertyTable;
$propertyType = 'N';                        //Тип свойства: 'N' - число
$query = PropertyTable::query();            //Получаем объект Bitrix\Main\ORM\Query\Query
$query->setFilter([                         //Устанавливаем фильтр
    '=IBLOCK_ID' => CATALOG_IBLOCK_ID,
    '=PROPERTY_TYPE' => $propertyType,
]);
$query->setSelect(['CODE']);                //Устанавливаем список получаемых полей
$properties = $query->exec()->fetchAll();   //Делаем запрос и получаем данные в виде массива

Более сложный пример получения данных с помощью Bitrix\Main\Entity\Query:

use Bitrix\Main\Entity\Query;
use Bitrix\Main\Entity\ExpressionField;
use Bitrix\Main\Entity\ReferenceField;

$query = new Query(Bitrix\Iblock\ElementPropertyTable::getEntity());
$query->setSelect([
    "VALUE",
    new ExpressionField("LENGTH_VALUE", "LENGTH(%s)", "VALUE") // Вычисляемое выражение (подробности ниже)
]);
$query->setFilter([
    'IBLOCK_PROPERTY_ID' => PROP_AUCTION_STATUS_ID,
    'IBLOCK_ELEMENT_ID' => $auctionId
]);
$query->registerRuntimeField(new ReferenceField( //Подзапрос в другую таблицу (подробности ниже)
    "ENUM",
    "Bitrix\Iblock\PropertyEnumerationTable",
    ["=this.VALUE" => "ref.ID"]
));

$result = $query->exec(); // Выполнение запроса

while ($row = $result->fetch()) { // Обработка результатов в виде массива
    print_r($row);
}

Вычисляемое поле

Вычисляемое поле создается с помощью класса Bitrix\Main\Entity\ExpressionField. В конструктор этого класса передаются три аргумента:

  1. Название поля, которое мы получим в итоге — «LENGTH_VALUE».
  2. Выражение, которое будет использоваться для вычисления значения поля — «LENGTH(%s)».
  3. Имя поля, значение которого будет использоваться в выражении — «VALUE».

Таким образом, вычисляемое поле «LENGTH_VALUE» будет содержать длину значения поля «VALUE».

Bitrix\Main\Entity\ExpressionField позволяет использовать различные выражения для вычисления значений вычисляемых полей. Некоторые из наиболее часто используемых выражений:

  • Математические выражения: +, -, *, /, %. Например, вычисление суммы двух полей: «%s + %s», где %s — это специальный символ, который будет заменен на значения полей.
  • Функции: COUNT(), SUM(), AVG(), MIN(), MAX(), LENGTH(), CONCAT(), SUBSTRING(), DATE_FORMAT(), NOW(), UNIX_TIMESTAMP(), FROM_UNIXTIME(), и другие. Например, вычисление среднего значения поля: «AVG(%s)».
  • Логические выражения: AND, OR, NOT, =, !=, <, >, <=, >=, BETWEEN, IN, LIKE, REGEXP. Например, выборка записей, где значение поля больше 10: «%s > 10».
  • Выражения с условиями: CASE, IF, IFNULL, COALESCE. Например, вычисление значения поля на основе условия: «CASE WHEN %s > 10 THEN ‘больше 10’ ELSE ‘меньше или равно 10’ END».
  • Выражения с подзапросами: EXISTS, NOT EXISTS, IN, NOT IN, ANY, ALL, SOME, UNION, INTERSECT, EXCEPT. Например, выборка записей, где значение поля равно максимальному значению в другой таблице: «%s = (SELECT MAX(field) FROM table2)».

Это лишь некоторые примеры выражений, которые можно использовать в Bitrix\Main\Entity\ExpressionField. В зависимости от конкретной задачи можно использовать и другие выражения.

Описание подзапросов есть ниже при использовании Bitrix\Main\Entity\Query, они делаются так же, как и через описанный ниже метод.

Работа с кастомными таблицами

Чтобы работать с кастомной таблицей, сначала нужно создать класс для работы с ней. Пример такого класса:

namespace Custom\Model; //описываем пространство имен для нашей таблицы

use Bitrix\Main\Entity; //подключаем для работы с сущностями БД (CRUD)

class DraftTable extends Entity\DataManager //обязательно наследовать свою таблицу от Entity\DataManager И обязательно чтобы название класса заканчивалось на ...Table
{
    public static function getTableName(): string //вернет название таблицы
    {
        return 'custom_draft_table';
    }

    public static function getMap() //при создании кастомной таблицы, в ней будут созданы такие поля
    {
        return array(
            new Entity\IntegerField(
                'ID',
                array(
                'primary' => true,
                'autocomplete' => true,
            )),
            new Entity\IntegerField(
                'USER_ID',
                array(
                'required' => true,
            )),
            new Entity\DatetimeField(
                'DATE_CREATE',
                array(
                'default_value' => new \Bitrix\Main\Type\DateTime(),
            )),
            new Entity\TextField('INFO'),
        );
    }

    public static function dropTable() //метод для удаления таблицы
    {
        $connection = \Bitrix\Main\Application::getConnection();
        $connection->dropTable(self::getTableName());
    }
}

Посмотреть типы данных и атрибуты при создании полей кастомной таблицы, можно в статье «Типы данных при создании кастомных таблиц«.

В рамках соблюдения стандартов кодирования, битрикс рекомендует называть поля таблиц в верхнем регистре. Для добавления таблицы воспользуемся следующим кодом:

if (!Custom\Model\DraftTable::getEntity()->getConnection()->isTableExists(Custom\Model\DraftTable::getTableName())) {
    Custom\Model\DraftTable::getEntity()->createDbTable();
}

Для добавления записи в созданную таблицу можно использовать следующий код (вернет объект Bitrix\Main\ORM\Data\AddResult). Для получения ID новой записи использовать GetId

use Custom\Model\DraftTable;

$result = DraftTable::add(array(
    'USER_ID' => $USER->GetID(),
    'DATE_CREATE' => new DateTime(),
    'INFO' => json_encode($itemInfoDraft),
));

Для обновления записи в кастомной таблице битрикс можно использовать следующий код:

use Custom\Model\DraftTable;

$result = DraftTable::update(
    $primaryKeyId, //ID записи в таблице
    array(
    'USER_ID' => $newUserId,
    'DATE_CREATE' => new DateTime(),
    'INFO' => json_encode($newInfo),
));

Для удаления записи из кастомной таблицы используем код:

use Custom\Model\DraftTable;

// Удаляем запись
$result = DraftTable::delete($primaryKeyId);

Для проверки исполнения кода (добавления/удаления/обновления), можно использовать следующий код:

if ($result->isSuccess()) {
    echo 'Запись успешно удалена.';
} else {
    $errors = $result->getErrorMessages();
    echo 'Ошибка при удалении записи: ' . implode(', ', $errors);
}

Во всех случаях, $result будет содержать объект результата действия (например, Bitrix\Main\ORM\Data\AddResult или Bitrix\Main\ORM\Data\DeleteResult).

Подзапросы с использованием метода join() (через runtime)

Чтобы не делать несколько отдельных запросов в БД, можно использовать функционал подзапросов. Вот пример кода:

$auctionStatus = \Bitrix\Iblock\ElementPropertyTable::getList([
    'filter' => [ // Фильтруем значения - для таблицы ElementPropertyTable
        'IBLOCK_PROPERTY_ID' => PROP_AUCTION_STATUS_DATA['ID'],
        'IBLOCK_ELEMENT_ID' => $auctionId
    ],
    'select' => [ // Выбираем поле 'VALUE' из таблицы ElementPropertyTable и поле 'XML_ID' из таблицы PropertyEnumerationTable
        'VALUE',
        //Использовать одно из трех значений:
        //'ENUM.XML_ID',                    // 1. Можно использовать такую форму записи. Тогда результат выборки будет таким: IBLOCK_ELEMENT_PROPERTY_ENUM_XML_ID => 25 
        'ENUM_XML_ID' => 'ENUM.XML_ID'      // 2. Чтобы название было аккуратным, прописываем "ENUM_XML_ID". Именно такой ключ будет иметь выбранное из БД значение. Теперь результат выборки будет таким: ENUM_XML_ID => 25
        //'ENUM_XML_ID' => 'ENUM'           // 3. Результат выборки - все значения из таблицы PropertyEnumerationTable для выбранного ID. Ну и VALUE (из таблицы ElementPropertyTable)
    ],
    'runtime' => [
        new \Bitrix\Main\Entity\ReferenceField(
            'ENUM', // Имя для создаваемого объекта ReferenceField. Это имя может быть любым
            'Bitrix\Iblock\PropertyEnumerationTable', // Добавляем ссылку на таблицу PropertyEnumerationTable с помощью метода ReferenceField()
            array('=this.VALUE' => 'ref.ID') // Связываем поле VALUE из таблицы ElementPropertyTable и поле ID из таблицы PropertyEnumerationTable - для фильтрации по ID
        )
    ]
])->fetch();

Строка «ENUM» в «ReferenceField» — это имя для создаваемого объекта ReferenceField. Это имя может быть любым, но обычно используется имя, которое отражает суть связи между таблицами.Таким образом, строка «ENUM.XML_ID» означает, что мы делаем выборку поля «XML_ID» из таблицы «PropertyEnumerationTable».

Работа с инфоблоками и любыми данными инфоблоков

Для работы с инфоблоками и любыми данными, которые в них находятся можно использовать следующую конструкцию:

$iblockClass = \Bitrix\Iblock\Iblock::wakeUp($iblockId)->getEntityDataClass();

Не стоит забывать, что в объекте инфоблока будет храниться информация о самом инфоблоке, включая свойства настройки и прочие параметры. Это может включать название инфоблока, его тип, доступные поля и свойства, права доступа, настройки сортировки, фильтры и другие атрибуты, которые определяют поведение и структуру инфоблока. Также, с помощью объекта, содержащегося в $iblockClass, можно работать с элементами инфоблока.

Не стоит забывать — чтобы метод wakeUp() отработал без ошибок, в инфоблоке должна быть задана настройка «Символьный код API».

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

$iblockClass = \Bitrix\Iblock\Iblock::wakeUp($arParams['IBLOCK_ID'])->getEntityDataClass(); //получаем объект 
$select = [
    'PREVIEW_PICTURE', 
    'MAIN_VALUE' => 'MAIN.VALUE', //свойство "MAIN", из которого мы забираем VALUE для конкретного элемента инфоблока
    'IBLOCK_SECTION_ID', //ID раздела
    'SHOW_COUNTER', //кастомное значение в таблице элементов
    'DETAIL_PAGE_URL_RAW' => 'IBLOCK.DETAIL_PAGE_URL', //получаем DETAIL_PAGE_URL
    'CODE' 
];
$elCatalog = $iblockClass::getList([
    'order' => array('ACTIVE_FROM'=>'DESC','ID'=>'DESC'),
    'filter' => array(
        'IBLOCK_ID'=>$arParams['IBLOCK_ID'], 
        'ACTIVE'=>'Y', 
        //'MAIN_VALUE'=> '41' // в $select задана MAIN_VALUE, значит здесь пишем так же
        'LOGIC' => 'OR', 
        [
           'MAIN_VALUE' => '41',
        ],
        [
           'MAIN_VALUE' => '42', // Второе условие для "или"
        ],
    ),
    'limit' => 1, //достаем всего один элемент
    'select' => $select
])->fetch();
$elCatalog['DETAIL_PAGE_URL'] = \CIBlock::ReplaceDetailUrl($elCatalog["DETAIL_PAGE_URL_RAW"], $elCatalog, true, "E"); //получаем URL деталки элемента (для корректного формирования обязательно передавать "IBLOCK_ID", "CODE", "IBLOCK_SECTION_ID", "IBLOCK.DETAIL_PAGE_URL_RAV")
$elCatalog['PREVIEW_PICTURE'] = CFile::GetFileArray($elCatalog['PREVIEW_PICTURE']); //получаем массив с данными по ID изображения

Примеры использования

Выборка ID, NAME для элементов инфоблока (например, каталога):

$all_el_catalog = \Bitrix\Iblock\ElementTable::getList([
    'select' => ['ID', 'NAME'],
    'filter' => ['IBLOCK_ID' => $ib_id],
])->fetchAll();

Выборка ID элементов по свойству, у которых:

  • заполнено свойство $prop_id;
  • ID элемента находится в массиве $all_el_catalog
$all_el_catalog = \Bitrix\Iblock\ElementTable::getList([
    'select' => ['ID', 'NAME'],
    'filter' => ['IBLOCK_ID' => $ib_id],
])->fetchAll();

Выборка  данных из кастомной таблицы:

use \Bitrix\Main;

$test_xml_id = 'fffff';
$query = "SEL ECT `DATA` FROM user_table WHERE `XML_ID` = '$test_xml_id'";

try
{
    $connection = Main\Application::getInstance()->getConnection();
    $queryResult = $connection->query($query);

    foreach ($queryResult as $data)
    {
        var_dump( (array) $data );
    }
}
catch( Main\DB\SqlException $e )
{
    var_dump($e->getMessage());
}

Получение ID раздела по его символьному коду:

$section_id = \Bitrix\Iblock\SectionTable::getList([
    'select' => ['ID'],
    'filter' => ['CODE' => $section_code],
])->fetch();
Сергей Житников
Об авторе

Сергей Житников - Веб-разработчик

Занимаюсь веб-разработкой более 5 лет. Специализируюсь на создании адаптивных сайтов и веб-приложений на HTML5, CSS3 и JavaScript. Работаю с популярными CMS и фреймворками, а также уделяю большое внимание оптимизации производительности и чистоте кода.

Есть проект или идея? Буду рад помочь!

Связаться со мной

Последние статьи

19.06.2026
В статье собрал шпаргалку по основным компонентам Bitrix: bitrix:menu, news.list, news.detail, sale.basket.basket.line, main.include и breadcrumb. Разобрал настройку меню из разделов и элементов инфоблока через файлы .menu_ext.php, показываю полные конфигурации компонентов с пояснениями ключевых параметров. Готовые примеры для быстрого копирования и использования в проектах.
19.06.2026
Купоны в Битрикс неразрывно связаны с правилами работы с корзиной — без привязки к правилу они не сработают, а правило без купонов применит скидку на все товары. Разбираю создание купонов через DiscountCouponTable::add(): обязательные и опциональные поля, типы купонов, флаги активности. Показываю примеры работы с датами через объект DateTime (прибавление дней, месяцев и минут).
19.06.2026
Разбираю готовые примеры работы с изображениями в PHP: сохранение на сервер, вывод в браузер, рисование линий и прямоугольников. Отдельно — нюансы с форматами файлов (JPEG/PNG) и поддержкой кириллицы через шрифты.