Highload-блок на практике - создание, поля, привязка к свойству
Заводим справочник в highload-блоке: создаём блок и поля, получаем класс для запросов и привязываем всё это к свойству товара.
Решение
Создаём блок и его поля:
use Bitrix\Highloadblock\HighloadBlockTable;
$result = HighloadBlockTable::add(['NAME' => 'Brands', 'TABLE_NAME' => 'vendor_brands']);$hlId = $result->getId();// имя сущности пишется с большой буквы и без пробелов: по нему собирается класс// имя таблицы - строчными буквами, оно попадает прямо в базу данныхИмя сущности и имя таблицы задаются при создании и потом не меняются. По имени сущности платформа собирает класс, поэтому переименование блока на живом проекте ломает весь код, который к нему обращается.
Получаем класс сущности для запросов:
$hlblock = HighloadBlockTable::getById($hlId)->fetch();$entity = HighloadBlockTable::compileEntity($hlblock);$dataClass = $entity->getDataClass();
$dataClass::add(['UF_NAME' => 'Пример', 'UF_XML_ID' => 'primer']);$rows = $dataClass::getList(['select' => ['ID', 'UF_NAME'], 'limit' => 20])->fetchAll();Класс сущности собирается на лету по идентификатору блока. Готового имени класса в коде нет, поэтому обращение к справочнику всегда начинается с этих двух строк, и их удобно спрятать в свой метод.
Привязываем справочник к свойству товара:
$prop = new CIBlockProperty();$prop->Update($propertyId, [ 'USER_TYPE' => 'directory', 'USER_TYPE_SETTINGS' => ['TABLE_NAME' => 'vendor_brands'],]);// свойство хранит внешний код записи, а показывает её названиеСвойство типа «справочник» хранит внешний код записи, а не её название. Отсюда требование к данным: у каждой записи должен быть заполнен внешний код, иначе свойство сохранит пустоту.
Переносим данные между стендами:
foreach ($dataClass::getList(['select' => ['*']])->fetchAll() as $row) { // выгружаем в файл и загружаем на другом стенде по внешнему коду printf("%s;%s\n", $row['UF_XML_ID'], $row['UF_NAME']);}Структуру блока переносят вместе с кодом, а записи - отдельно. Справочник, существующий только на боевом сайте, превращает стенд разработчика в место, где половина товаров без брендов.
Обёртку над получением класса стоит написать один раз и держать в своём модуле. Иначе две строки сборки сущности расползаются по проекту, а при переименовании блока их приходится искать по всему коду.
Названия полей справочника начинают с приставки пользовательских полей. Это не украшение: платформа отличает их от служебных именно по ней, и поле без приставки в сущность не попадёт.
Фильтрация по свойству-справочнику работает через фасетный индекс, как и у обычных свойств. После массовой заливки справочника индекс пересобирают, иначе фильтр не покажет новые значения.
Highload-блок не заменяет инфоблок там, где нужны разделы, права на записи и привязка файлов. Он выигрывает на однотипных данных, и именно этим и стоит руководствоваться при выборе.
Типичные проблемы
Код перестал находить справочник.
Изменилось имя сущности блока. Класс собирается по этому имени, и переименование ломает все обращения.
Свойство товара сохраняет пустоту.
У записей справочника не заполнен внешний код. Свойство хранит именно его, а не название записи.
На стенде товары без значений свойства.
Записи справочника остались на боевом сайте. Структура переносится с кодом, данные - отдельно.
Фильтр не показывает новые значения.
Фасетный индекс не пересобран после заливки справочника. Он хранит готовые связки значений с разделами.
В справочнике не хватает разделов и прав.
Их у highload-блока нет по устройству. Для таких данных берут инфоблок.
Частые вопросы
Как быстро наполнить справочник?
Скриптом с обходом файла и записью через класс сущности. Через интерфейс это разумно только для десятков записей.
Можно ли хранить картинки в справочнике?
Да, полем типа файл: так делают справочники брендов с логотипами. Множественные галереи лучше держать в инфоблоке.
Как показать название вместо кода?
Через свойство типа «справочник»: компонент сам подставит название. При своей выборке название запрашивают у сущности.
Есть ли ограничение по числу записей?
Практически нет: хранилище рассчитано на большие справочники. Ограничивает скорее интерфейс правки, чем сама таблица.
Смежное
-
Highload-блоки на практике - оглавление подтемы
-
Где хранить данные: инфоблок, highload-блок или своя таблица - выбор между тремя хранилищами
-
Highload-блоки - устройство хранилища
-
Свойства-привязки: элемент, раздел и обратная выборка - соседний способ ссылаться
-
Своя таблица на ORM: сущность, запросы, изменение структуры - когда интерфейс не нужен
-
Инфоблоки - устройство хранилища целиком
-
Highload-блок на объёме: индексы, заливка, выкладка структуры - когда записей десятки тысяч
-
Справочник в выборках: вывод значений, фильтр, кэш - как его читают на витрине
-
Список как справочник: поля, права, вывод и наполнение - когда справочник ведёт сотрудник
-
Запись на услугу: слоты, занятость, защита от двойной брони - справочник как хранилище броней
-
Справочник не отдаёт значения: разбор причин - разбор пустых значений свойства