Архитектура и основные объекты
Highload-блок состоит из описания набора данных, пользовательских полей и записей. Модуль связывает эти слои по идентификатору блока и во время выполнения формирует ORM-объект для работы с записями.
При проектировании полей и переносе структуры разделяйте операции с описанием блока и его записями. Для управления описанием используйте HighloadBlockTable, а для работы с записями — класс данных, который возвращает HighloadBlockTable::compileEntity().
Если способ хранения еще не выбран, сравните Highload-блок, информационный блок и собственный ORM-класс в статье Введение и базовые концепции.
Слои Highload-блока
Описание блока не содержит сами записи. В описании хранятся имя ORM-объекта и название таблицы с записями. Каждое пользовательское поле добавляет записи отдельное свойство и задает его название, тип и настройки.
Описание Highload-блока
├── ID, NAME и TABLE_NAME
├── локализованные названия
├── правила доступа
└── идентификатор пользовательских полей HLBLOCK_<ID>
└── пользовательские поля UF_*
└── отдельная таблица записей
├── системное поле ID
├── одиночные значения
└── множественные значения и их дополнительное хранилище
Связь между слоями строится вокруг поля ID описания блока:
-
значение
HLBLOCK_<ID>объединяет блок с реестром пользовательских полей, -
значение
TABLE_NAMEсвязывает описание с таблицей записей, -
значение
NAMEопределяет имя динамического ORM-объекта и класса данных, -
поле
HL_IDсвязывает правило доступа с блоком, -
пара
IDиLIDсвязывает локализованное название с блоком и языком.
Метаданные блока
Класс Bitrix\Highloadblock\HighloadBlockTable управляет описаниями Highload-блоков. Его карта содержит основные поля и вычисляемые связи:
-
ID— автоматически создаваемый целочисленный идентификатор блока, -
NAME— имя ORM-объекта, которое участвует в имени динамического класса данных, -
TABLE_NAME— имя отдельной таблицы с записями блока, -
FIELDS_COUNT— вычисляемое количество пользовательских полей с идентификаторомHLBLOCK_<ID>, -
LANG— ORM-связь с локализованным названием блока для текущего языка.
Класс HighloadBlockTable отвечает не только за строку описания. При добавлении, переименовании таблицы и удалении блока класс синхронизирует метаданные со схемой хранения. Поэтому не изменяйте описание блока и структуру таблиц прямыми запросами к базе данных.
Связанные классы метаданных
Дополнительные классы отделяют локализацию и правила доступа от основного описания.
|
Класс |
Что делает |
Ключевые поля |
|
|
Хранит название блока для конкретного языка |
|
|
|
Связывает блок, задачу доступа и код субъекта доступа |
|
|
|
Содержит данные одного Highload-блока из |
|
При запросах через динамический ORM-класс правила доступа из HighloadBlockRightsTable не применяются автоматически. Перед прямой работой с классом данных приложение должно отдельно проверить, разрешена ли нужная операция. Настройка доступа описана в статье События записей и права доступа.
Пользовательские поля и записи
Каждому Highload-блоку соответствует идентификатор пользовательских полей вида HLBLOCK_<ID>. Например, для блока с идентификатором 7 модуль использует значение HLBLOCK_7. По этому ключу менеджер пользовательских полей получает карту UF_*, которую compileEntity() добавляет к ORM-объекту записей.
Таблица записей появляется вместе с блоком. Сначала она содержит только автоматически создаваемое целочисленное поле ID. При добавлении пользовательского поля модуль добавляет в таблицу колонку с именем поля и типом хранения, который соответствует типу пользовательского поля.
Общие типы и настройки полей описаны в статье Пользовательские поля. Порядок создания и изменения полей Highload-блока приведен в статье Создание, настройка и перенос Highload-блоков.
Одиночные значения
Одиночное пользовательское поле становится скалярным полем ORM-объекта. Значение хранится в колонке основной записи. Настройка MANDATORY определяет признак обязательности поля в динамической ORM-карте.
Тип пользовательского поля определяет PHP-представление, преобразование перед сохранением и дополнительные ORM-связи. Например, тип привязки к элементам Highload-блока может добавить поле-ссылку с окончанием _REF.
Для настройки привязок и служебных полей справочников используйте рекомендации из статьи Связи и справочники на Highload-блоках.
Множественные значения
Для множественного поля модуль создает дополнительное хранилище значений. Каждая строка в нем связывает ID основной записи с одним значением поля. Модуль также поддерживает представление массива в основной записи и синхронизирует оба представления через Bitrix\Highloadblock\DataManager.
В ORM-карте множественное поле доступно как массив. Дополнительное выражение с окончанием _SINGLE позволяет обращаться к отдельным значениям через связь со вспомогательным ORM-объектом.
Не изменяйте основную таблицу и дополнительное хранилище множественного поля независимо. Прямые запросы могут нарушить согласованность представлений. Добавляйте и изменяйте записи через динамический класс данных.
Динамический ORM-объект
Метод HighloadBlockTable::compileEntity() принимает описание блока, его идентификатор или имя. Метод проверяет описание, создает ORM-карту из системного поля ID и пользовательских полей, затем возвращает объект Bitrix\Main\ORM\Entity.
Класс данных наследует Bitrix\Highloadblock\DataManager. Его имя формируется по шаблону \<NAME>Table в глобальном пространстве имен, а метод getTableName() возвращает значение TABLE_NAME из описания блока.
Пример. Получите описание существующего Highload-блока и его класс данных. Перед запуском передайте идентификатор блока в переменной $highloadBlockId.
use Bitrix\Highloadblock\HighloadBlockTable;
use Bitrix\Main\Loader;
if (!Loader::includeModule('highloadblock'))
{
throw new \RuntimeException('Не удалось подключить модуль highloadblock');
}
$highloadBlock = HighloadBlockTable::getById($highloadBlockId)->fetch();
if (!$highloadBlock)
{
throw new \RuntimeException('Highload-блок не найден');
}
$entity = HighloadBlockTable::compileEntity($highloadBlock);
$dataClass = $entity->getDataClass();
Переменная $entity содержит ORM-описание, а $dataClass — полное имя класса для запросов и изменений записей. Для запросов, изменения записей и обработки ошибок используйте примеры из статьи Работа с записями.
Обновить ORM-объект после изменения структуры
При первом вызове compileEntity() в текущем запросе модуль создает PHP-класс и ORM-карту. Повторный вызов возвращает созданный объект. Второй аргумент true уничтожает прежнее ORM-описание и строит карту заново, но не переопределяет уже загруженный PHP-класс.
Выбирайте действие по типу изменения:
|
Изменение |
Как продолжить работу |
|
Структура не менялась |
Используйте уже полученный класс данных. Повторная компиляция не нужна |
|
Поле добавлено, изменено или удалено через |
Продолжите работу с записями в новом запросе. Если сценарий должен завершиться в текущем запросе, получите описание блока заново, вызовите |
|
Изменено поле |
Продолжите работу в новом запросе, чтобы код использовал новое имя PHP-класса |
|
Изменено только поле |
Продолжите работу в новом запросе. Аргумент |
Методы Add(), Update() и Delete() класса CUserTypeEntity очищают кеш менеджера пользовательских полей. Принудительная компиляция пересобирает ORM-карту по обновленному реестру, но не заменяет новый запрос для изменений имени класса или таблицы.
Изменение структуры
Методы управления структурой изменяют метаданные и хранилище поэтапно. При ошибке уже выполненные шаги могут сохраниться. Не запускайте изменение одного блока параллельно в нескольких процессах.
Перед удалением или переименованием подготовьте резервную копию. После каждой операции проверяйте объект результата и прекращайте зависимые шаги после ошибки. Порядок создания, переименования, удаления и повторяемой миграции приведен в статье Создание, настройка и перенос Highload-блоков.
Имена объектов
Поле NAME определяет имя динамического PHP-класса, а TABLE_NAME — имя хранилища записей. Код пользовательского поля имеет вид UF_*. Окончание _REF зарезервировано для ORM-ссылок, поэтому модуль отклоняет такое имя поля.
Точные ограничения длины, допустимых символов и уникальности собраны в разделе Подготовить имена и подключить модуль.
Связанные материалы
Класс HighloadBlockTable управляет описанием и схемой блока. Динамический класс на базе Bitrix\Highloadblock\DataManager работает с записями. Подробные сценарии сгруппированы по задачам:
-
управление блоком и полями — в статье Создание, настройка и перенос Highload-блоков,
-
выборка и изменение записей — в статье Работа с записями,
-
события и проверка разрешений — в статье События записей и права доступа,
-
индексы и диагностика — в статье Производительность и частые ошибки.
Highload-блок связывает настраиваемую схему пользовательских полей с отдельным хранилищем записей и динамической ORM-картой. Сохраняйте эту связь через API модуля: прямое изменение одного слоя не обновляет остальные автоматически.