Блог разработчика 1С-Битрикс

CIBlockType в 1С-Битрикс: полное руководство с рабочими примерами

CIBlockType — класс ядра Битрикс для управления *типами информационных блоков* (ИБ).

CIBlockType: руководство с примерами

С его помощью вы:

  • создаёте и изменяете типы,
  • получаете списки и конкретные записи,
  • храните локализацию названий (NAME/SECTION_NAME/ELEMENT_NAME),
  • удаляете типы (и все ИБ внутри него).

Ниже — краткая теория и много практики: готовые, самодостаточные куски кода без сокращений, с аккуратной обработкой ошибок и поправками на частые огрехи.


Быстрый справочник по методам

  • CIBlockType::GetList(array $arOrder = ["SORT"=>"ASC"], array $arFilter = [])CDBResult
    Список типов по фильтру/сортировке. Для сортировки по NAME нужен фильтр LANGUAGE_ID.
  • CIBlockType::GetByID(string $ID)CDBResult
    Тип по коду.
  • CIBlockType::GetByIDLang(string $ID, string $LANGUAGE_ID, bool $bFindAny = true)array|false
    Тип + языковые поля для конкретного языка. Если не найдено и $bFindAny = true, вернёт дефолтный язык.
  • $ob = new CIBlockType; $ob->Add(array $arFields)string|false
    Добавляет тип. В реальном ядре возвращает ID типа (строку) или false. Ошибки → $ob->LAST_ERROR.
    > В старых описаниях встречается «возвращает bool», но по факту — строка ID или false.
  • $ob->Update(string $ID, array $arFields)bool
    Изменяет тип. Ошибки → $ob->LAST_ERROR.
  • CIBlockType::Delete(string $ID)bool
    Удаляет тип и все ИБ внутри него. Опасная операция: будьте осторожны.

Разрешённые символы в ID: латиница, цифры, нижнее подчёркивание. Дефисы и пробелы — нельзя.


Подготовка окружения (важно)

Во всех примерах предполагается подключение модуля ИБ:

<?php
define('NO_KEEP_STATISTIC', true);
define('NOT_CHECK_PERMISSIONS', true);
require($_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/main/include/prolog_before.php');
if (!\Bitrix\Main\Loader::includeModule('iblock')) {
    die('Модуль iblock не подключен');
}

GetList: выборки и сортировки

1) Базовый список всех типов

<?php
$rs = CIBlockType::GetList(
    ["SORT" => "ASC"], // сортировка по индексу
    []                 // без фильтра
);
while ($ar = $rs->Fetch()) {
    // Для красивого вывода используем безопасное экранирование
    echo htmlspecialcharsbx($ar['ID']).' (SORT: '.(int)$ar['SORT'].')<br>';
}

2) Сортировка по NAME (обязательно добавить LANGUAGE_ID)

<?php
$rs = CIBlockType::GetList(
    ["NAME" => "ASC"],                 // сортировка по названию типа
    ["LANGUAGE_ID" => LANGUAGE_ID]     // язык обязателен при сортировке по NAME
);
while ($ar = $rs->Fetch()) {
    // Получим языковые подписи для выбранного языка
    $lang = CIBlockType::GetByIDLang($ar['ID'], LANGUAGE_ID);
    if ($lang) {
        echo htmlspecialcharsbx($lang['NAME']).' ['.htmlspecialcharsbx($ar['ID']).']<br>';
    }
}

3) Фильтр по подстроке в коде (ID) — регистронезависимо

<?php
$rs = CIBlockType::GetList(
    ["ID" => "ASC"],
    ["ID" => "%cat%"] // подстрока
);
while ($ar = $rs->Fetch()) {
    echo htmlspecialcharsbx($ar['ID']).'<br>';
}

4) Точное совпадение и выборка «IN» по множеству ID

<?php
$rs1 = CIBlockType::GetList([], ["=ID" => "catalog"]);      // строгое совпадение
$rs2 = CIBlockType::GetList([], ["=ID" => ["news", "blog"]]); // IN по массиву
while ($ar = $rs1->Fetch()) {
    echo 'Found exact: '.htmlspecialcharsbx($ar['ID']).'<br>';
}
while ($ar = $rs2->Fetch()) {
    echo 'Found in set: '.htmlspecialcharsbx($ar['ID']).'<br>';
}

5) Фильтр по NAME (во всех языках)

<?php
$rs = CIBlockType::GetList([], ["NAME" => "каталог"]);
while ($ar = $rs->Fetch()) {
    $ru = CIBlockType::GetByIDLang($ar['ID'], 'ru');
    $en = CIBlockType::GetByIDLang($ar['ID'], 'en');
    echo '['.htmlspecialcharsbx($ar['ID']).'] '.
         ($ru ? htmlspecialcharsbx($ru['NAME']) : '—').' / '.
         ($en ? htmlspecialcharsbx($en['NAME']) : '—').
         '<br>';
}

GetByID / GetByIDLang: точечный доступ

6) Получить тип по коду

<?php
$rs = CIBlockType::GetByID('catalog');
$ar = $rs->Fetch();
if ($ar) {
    echo '<pre>'.htmlspecialcharsbx(print_r($ar, true)).'</pre>';
} else {
    echo 'Тип не найден';
}

7) Получить локализованные названия для текущего языка

<?php
$arLang = CIBlockType::GetByIDLang('catalog', LANGUAGE_ID);
if ($arLang !== false) {
    echo 'Название типа: '.htmlspecialcharsbx($arLang['NAME']).'<br>';
    echo 'Разделы: '.htmlspecialcharsbx($arLang['SECTION_NAME']).'<br>';
    echo 'Элементы: '.htmlspecialcharsbx($arLang['ELEMENT_NAME']).'<br>';
} else {
    echo 'Локализация не найдена';
}

Add: создание типа

8) Минимально корректное создание RU/EN типа с транзакцией

<?php
global $DB;
$fields = [
    'ID'        => 'catalog',
    'SECTIONS'  => 'Y', // будут разделы
    'IN_RSS'    => 'N',
    'SORT'      => 100,
    'LANG'      => [
        'ru' => [
            'NAME'         => 'Каталог',
            'SECTION_NAME' => 'Разделы',
            'ELEMENT_NAME' => 'Товары',
        ],
        'en' => [
            'NAME'         => 'Catalog',
            'SECTION_NAME' => 'Sections',
            'ELEMENT_NAME' => 'Products',
        ],
    ],
];
$obType = new CIBlockType();
$DB->StartTransaction();
$id = $obType->Add($fields); // ВОЗВРАЩАЕТ СТРОКУ ID ИЛИ false
if (!$id) {
    $DB->Rollback();
    echo 'Ошибка: '.$obType->LAST_ERROR;
} else {
    $DB->Commit();
    echo 'Создан тип: '.htmlspecialcharsbx($id);
}

9) Защита от повторного создания (ensure)

<?php
function ensureIblockType(array $fields): string
{
    $typeId = (string)$fields['ID'];
    $exists = CIBlockType::GetByID($typeId)->Fetch();
    if ($exists) {
        return $typeId; // уже есть
    }
    $ob = new CIBlockType();
    global $DB;
    $DB->StartTransaction();
    $id = $ob->Add($fields);
    if (!$id) {
        $DB->Rollback();
        throw new \RuntimeException('Не удалось создать тип "'.$typeId.'": '.$ob->LAST_ERROR);
    }
    $DB->Commit();
    return $id;
}
// Пример вызова:
ensureIblockType([
    'ID'       => 'blog',
    'SECTIONS' => 'N',
    'IN_RSS'   => 'N',
    'SORT'     => 200,
    'LANG'     => [
        'ru' => ['NAME' => 'Блог', 'SECTION_NAME' => '', 'ELEMENT_NAME' => 'Записи'],
        'en' => ['NAME' => 'Blog', 'SECTION_NAME' => '', 'ELEMENT_NAME' => 'Posts'],
    ],
]);

Update: изменение параметров/локализации

10) Простое изменение свойств и локализации

<?php
global $DB;
$ob = new CIBlockType();
$fields = [
    'SECTIONS' => 'Y',
    'IN_RSS'   => 'N',
    'SORT'     => 120,
    'LANG'     => [
        'ru' => [
            'NAME'         => 'Каталог товаров',
            'SECTION_NAME' => 'Категории',
            'ELEMENT_NAME' => 'Товары',
        ],
        'en' => [
            'NAME'         => 'Product catalog',
            'SECTION_NAME' => 'Categories',
            'ELEMENT_NAME' => 'Products',
        ],
    ],
];
$DB->StartTransaction();
$ok = $ob->Update('catalog', $fields);
if (!$ok) {
    $DB->Rollback();
    echo 'Ошибка: '.$ob->LAST_ERROR;
} else {
    $DB->Commit();
    echo 'Тип обновлён';
}

11) «Upsert» локализаций (добавление нового языка)

<?php
$ob = new CIBlockType();
global $DB;
$addLang = [
    'de' => [
        'NAME'         => 'Katalog',
        'SECTION_NAME' => 'Kategorien',
        'ELEMENT_NAME' => 'Produkte',
    ],
];
$DB->StartTransaction();
$ok = $ob->Update('catalog', ['LANG' => $addLang]);
if (!$ok) {
    $DB->Rollback();
    echo 'Ошибка: '.$ob->LAST_ERROR;
} else {
    $DB->Commit();
    echo 'Добавлена локализация DE';
}

Delete: безопасное удаление

Внимание: CIBlockType::Delete($ID) удаляет все ИБ этого типа. Перед удалением проверьте, нет ли важных данных.

12) Удаление с подсчётом ИБ и подтверждением

<?php
function countIblocksByType(string $type): int
{
    $rs = CIBlock::GetList([], ['=TYPE' => $type], false);
    $cnt = 0;
    while ($rs->Fetch()) { $cnt++; }
    return $cnt;
}
$type = 'catalog';
$cnt  = countIblocksByType($type);
if ($cnt > 0) {
    echo 'Нельзя удалять: найдено ИБ внутри типа ('.$cnt.'). Перенесите данные или удалите ИБ.';
} else {
    global $DB;
    $DB->StartTransaction();
    if (!CIBlockType::Delete($type)) {
        $DB->Rollback();
        echo 'Ошибка удаления';
    } else {
        $DB->Commit();
        echo 'Тип удалён';
    }
}

Массовые операции и конфигурация «как код»

13) Массовая регистрация типов из конфиг-массива

<?php
$typesConfig = [
    [
        'ID' => 'content',
        'SECTIONS' => 'Y',
        'IN_RSS' => 'N',
        'SORT' => 100,
        'LANG' => [
            'ru' => ['NAME' => 'Контент', 'SECTION_NAME' => 'Разделы', 'ELEMENT_NAME' => 'Материалы'],
            'en' => ['NAME' => 'Content', 'SECTION_NAME' => 'Sections', 'ELEMENT_NAME' => 'Materials'],
        ],
    ],
    [
        'ID' => 'forms',
        'SECTIONS' => 'N',
        'IN_RSS' => 'N',
        'SORT' => 200,
        'LANG' => [
            'ru' => ['NAME' => 'Формы', 'SECTION_NAME' => '', 'ELEMENT_NAME' => 'Ответы'],
            'en' => ['NAME' => 'Forms', 'SECTION_NAME' => '', 'ELEMENT_NAME' => 'Submissions'],
        ],
    ],
];
foreach ($typesConfig as $fields) {
    try {
        ensureIblockType($fields);
        echo 'Ок: '.htmlspecialcharsbx($fields['ID']).'<br>';
    } catch (\Throwable $e) {
        echo 'Ошибка: '.htmlspecialcharsbx($e->getMessage()).'<br>';
    }
}

14) Экспорт существующих типов в PHP-массив (для миграций)

<?php
function exportIblockTypes(): array
{
    $out = [];
    $rs  = CIBlockType::GetList(['ID' => 'ASC'], []);
    while ($t = $rs->Fetch()) {
        $id = $t['ID'];
        $langs = ['ru', 'en']; // добавьте нужные
        $langPack = [];
        foreach ($langs as $lid) {
            $ar = CIBlockType::GetByIDLang($id, $lid, false);
            if ($ar) {
                $langPack[$lid] = [
                    'NAME'         => (string)$ar['NAME'],
                    'SECTION_NAME' => (string)$ar['SECTION_NAME'],
                    'ELEMENT_NAME' => (string)$ar['ELEMENT_NAME'],
                ];
            }
        }
        $out[] = [
            'ID'       => $id,
            'SECTIONS' => $t['SECTIONS'],
            'IN_RSS'   => $t['IN_RSS'],
            'SORT'     => (int)$t['SORT'],
            'LANG'     => $langPack,
        ];
    }
    return $out;
}
$dump = exportIblockTypes();
echo '<pre>'.htmlspecialcharsbx(var_export($dump, true)).'</pre>';

15) Скрипт установки/удаления типов в модуле

<?php
// install.php вашего модуля: register types
function installIblockTypesForModule(): void
{
    $types = [
        [
            'ID' => 'project',
            'SECTIONS' => 'Y',
            'IN_RSS'   => 'N',
            'SORT'     => 150,
            'LANG'     => [
                'ru' => ['NAME' => 'Проекты', 'SECTION_NAME' => 'Группы', 'ELEMENT_NAME' => 'Проекты'],
                'en' => ['NAME' => 'Projects', 'SECTION_NAME' => 'Groups', 'ELEMENT_NAME' => 'Projects'],
            ],
        ],
    ];
    foreach ($types as $t) { ensureIblockType($t); }
}
// uninstall.php: remove types (если уверены!)
function uninstallIblockTypesForModule(): void
{
    $ids = ['project'];
    foreach ($ids as $id) {
        CIBlockType::Delete($id);
    }
}

Утилиты разработчика

16) Проверка корректности ID и подготовка полей

<?php
function prepareTypeFields(array $fields): array
{
    $fields['ID'] = preg_replace('/[^A-Za-z0-9_]/', '_', (string)$fields['ID']);
    $fields['SECTIONS'] = (isset($fields['SECTIONS']) && $fields['SECTIONS'] === 'Y') ? 'Y' : 'N';
    $fields['IN_RSS']   = (isset($fields['IN_RSS']) && $fields['IN_RSS'] === 'Y') ? 'Y' : 'N';
    $fields['SORT']     = isset($fields['SORT']) ? (int)$fields['SORT'] : 500;
    return $fields;
}

17) Печать таблицы типов (в админском скрипте)

<?php
$rs = CIBlockType::GetList(['SORT' => 'ASC'], []);
echo '<table border="1" cellpadding="5" cellspacing="0">';
echo '<tr><th>ID</th><th>SORT</th><th>NAME ('.LANGUAGE_ID.')</th><th>SECTIONS</th><th>IN_RSS</th></tr>';
while ($t = $rs->Fetch()) {
    $lang = CIBlockType::GetByIDLang($t['ID'], LANGUAGE_ID);
    echo '<tr>';
    echo '<td>'.htmlspecialcharsbx($t['ID']).'</td>';
    echo '<td>'.(int)$t['SORT'].'</td>';
    echo '<td>'.htmlspecialcharsbx($lang ? $lang['NAME'] : '').'</td>';
    echo '<td>'.htmlspecialcharsbx($t['SECTIONS']).'</td>';
    echo '<td>'.htmlspecialcharsbx($t['IN_RSS']).'</td>';
    echo '</tr>';
}
echo '</table>';

18) «Мягкое» удаление: перенос ИБ на другой тип (пример-подсказка)

<?php
/**
 * Переводит все ИБ с типа $fromType на $toType, затем удаляет $fromType.
 * Требует, чтобы $toType уже существовал.
 */
function migrateIblocksType(string $fromType, string $toType): bool
{
    // 1) Проверим, что целевой тип есть
    if (!CIBlockType::GetByID($toType)->Fetch()) {
        throw new \RuntimeException('Целевой тип не найден: '.$toType);
    }
    // 2) Пройдёмся по ИБ исходного типа и сменим им TYPE
    $ibRes = CIBlock::GetList([], ['=TYPE' => $fromType], false);
    while ($ib = $ibRes->Fetch()) {
        $u = new CIBlock();
        $ok = $u->Update($ib['ID'], ['IBLOCK_TYPE_ID' => $toType]);
        if (!$ok) {
            global $APPLICATION;
            $e = $APPLICATION->GetException();
            throw new \RuntimeException('Не удалось перенести ИБ #'.$ib['ID'].': '.($e ? $e->GetString() : 'Без деталей'));
        }
    }
    // 3) Теперь можно безопасно удалить тип
    return CIBlockType::Delete($fromType);
}
// Пример вызова:
// migrateIblocksType('old_type', 'catalog');

Частые ошибки и как их избежать

  1. Сортировка по NAME без LANGUAGE_ID в фильтре.
    Решение: всегда добавляйте ["LANGUAGE_ID" => LANGUAGE_ID] при ["NAME" => "..."] в arOrder.
  2. Неверное экранирование.
    Используйте htmlspecialcharsbx(...) для вывода.
  3. Ложные ожидания от Add().
    В реальном ядре Add() возвращает строку ID или false, а не true/false. Проверяйте как if (!$id) { ... }.
  4. Удаление типа с данными.
    Delete() уничтожает все ИБ типа. Сначала мигрируйте/экспортируйте данные или подтвердите, что их нет.
  5. Неверный ID.
    Разрешены только [A-Za-z0-9_]. Не используйте дефисы/пробелы.
  6. Пустой LANG при Add().
    Это ошибка валидации. Заполните хотя бы NAME для одного языка.

Расширенные примеры «на каждый день»

19) Поиск типа по человекочитаемому имени (любой язык)

<?php
function findTypeByName(string $name): array
{
    $found = [];
    $rs = CIBlockType::GetList([], ['NAME' => $name]);
    while ($t = $rs->Fetch()) {
        $ru = CIBlockType::GetByIDLang($t['ID'], 'ru');
        $en = CIBlockType::GetByIDLang($t['ID'], 'en');
        $found[] = [
            'ID' => $t['ID'],
            'RU' => $ru ? $ru['NAME'] : null,
            'EN' => $en ? $en['NAME'] : null,
        ];
    }
    return $found;
}
$result = findTypeByName('Каталог');
echo '<pre>'.htmlspecialcharsbx(print_r($result, true)).'</pre>';

20) Мини-API (скрипт) для выдачи JSON со списком типов

<?php
header('Content-Type: application/json; charset=utf-8');
$out = [];
$rs  = CIBlockType::GetList(['ID' => 'ASC'], ['LANGUAGE_ID' => LANGUAGE_ID]);
while ($t = $rs->Fetch()) {
    $lang = CIBlockType::GetByIDLang($t['ID'], LANGUAGE_ID);
    $out[] = [
        'id'       => $t['ID'],
        'sort'     => (int)$t['SORT'],
        'sections' => $t['SECTIONS'] === 'Y',
        'in_rss'   => $t['IN_RSS'] === 'Y',
        'name'     => $lang ? (string)$lang['NAME'] : '',
        'section'  => $lang ? (string)$lang['SECTION_NAME'] : '',
        'element'  => $lang ? (string)$lang['ELEMENT_NAME'] : '',
    ];
}
echo \Bitrix\Main\Web\Json::encode($out, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);

Вывод

CIBlockType — небольшое, но ключевое API Битрикс, от которого зависит архитектура контента. Освоив фильтры GetList, локализацию через GetByIDLang, аккуратные транзакции для Add/Update и осознанное использование Delete, вы легко автоматизируете установку/миграции проектов, поддержите чистоту данных и ускорите CI/CD для контент-структуры.

Теги:  CIBlockType, информационные блоки, примеры кода, руководство


Стоимость услуг по разработке и сопровождению сайтов на 1C-Битрикс

Разработка интернет-магазина с готовой версткой

от 4 недель

от 90 000 рублей

* указана минимальная стоимость. Стоимость выбранной лицензии «1С-Битрикс» оплачивается отдельно.

Лендинг

от 3 дней

от 25 000 рублей

Разработка одностраничного сайта на платформе Битрикс

* стоимость зависит от наличия верстки, использования готового решения и т.д.

Разработка корпоративного сайта

от 7 дней

от 40 000 рублей

Разработка сайта без системы оплаты заказов через корзину

* стоимость зависит от наличия верстки, использования готового решения и т.д.