Как получить раздел(ы) инфоблока по элементу в 1С-Битрикс

В 1С-Битрикс довольно часто возникает задача определения, к каким разделам принадлежит элемент инфоблока. Зная разные методы и функции, можно быстро получить нужную информацию о разделе по ID элемента, по символьному коду, а также извлечь корневой раздел или список всех разделов элемента.

Как получить раздел(ы) инфоблока по элементу в 1С-Битрикс

В этой статье мы рассмотрим способы решения задачи как на «старом ядре» (через классы CIBlockElement и CIBlockSection), так и более современным методом на D7-ядре (через ORM-классы Bitrix\Iblock\ElementTable, Bitrix\Iblock\SectionTable и т. д.).


1. Как получить раздел инфоблока по ID элемента

Старый метод (через CIBlockElement и CIBlockSection)

Самый прямолинейный способ — сначала получить данные самого элемента, узнать, какой у него основной раздел (IBLOCK_SECTION_ID), и затем по этому идентификатору запросить данные раздела.

Шаги:

  1. Использовать класс CIBlockElement и его метод GetByID, чтобы получить информацию об элементе.
  2. Из результата взять поле IBLOCK_SECTION_ID — это ID привязанного раздела (если элемент принадлежит только одному основному разделу).
  3. По IBLOCK_SECTION_ID вызвать CIBlockSection::GetByID и получить подробные данные нужного раздела.

Пример кода:

<?php
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");

$ELEMENT_ID = 123;

// 1. Получаем элемент
$elementRes = CIBlockElement::GetByID($ELEMENT_ID);
if ($elementData = $elementRes->GetNext()) {
    $sectionId = $elementData["IBLOCK_SECTION_ID"];

    if ($sectionId) {
        // 2. Получаем раздел
        $sectionRes = CIBlockSection::GetByID($sectionId);
        if ($sectionData = $sectionRes->GetNext()) {
            echo "ID раздела: " . $sectionData["ID"] . "<br>";
            echo "Название раздела: " . $sectionData["NAME"] . "<br>";
            echo "Код раздела: " . $sectionData["CODE"] . "<br>";
        } else {
            echo "Раздел не найден.";
        }
    } else {
        echo "У элемента нет основного раздела.";
    }
} else {
    echo "Элемент с таким ID не найден.";
}
?>

Новый метод (D7, через ElementTable и SectionTable)

В рамках D7 (ORM) мы используем классы из пространства имён Bitrix\Iblock.

  1. Подключаем модуль iblock с помощью Loader::includeModule("iblock");.
  2. Обращаемся к Bitrix\Iblock\ElementTable для получения данных об элементе.
  3. Извлекаем IBLOCK_SECTION_ID.
  4. По полученному IBLOCK_SECTION_ID делаем запрос к Bitrix\Iblock\SectionTable.

Пример кода:

<?php
use Bitrix\Main\Loader;
use Bitrix\Iblock\ElementTable;
use Bitrix\Iblock\SectionTable;

require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");

Loader::includeModule("iblock");

$ELEMENT_ID = 123;

// 1. Получаем элемент через ORM
$element = ElementTable::getList([
    "filter" => ["=ID" => $ELEMENT_ID],
    "select" => ["ID", "IBLOCK_ID", "IBLOCK_SECTION_ID", "CODE", "NAME"]
])->fetch();

if ($element) {
    $sectionId = $element['IBLOCK_SECTION_ID'];
    if ($sectionId) {
        // 2. Получаем раздел
        $section = SectionTable::getList([
            "filter" => ["=ID" => $sectionId],
            "select" => ["ID", "NAME", "CODE", "IBLOCK_ID", "IBLOCK_SECTION_ID"]
        ])->fetch();

        if ($section) {
            echo "ID раздела: " . $section["ID"] . "<br>";
            echo "Название раздела: " . $section["NAME"] . "<br>";
            echo "Код раздела: " . $section["CODE"] . "<br>";
        } else {
            echo "Раздел не найден.";
        }
    } else {
        echo "У элемента нет основного раздела.";
    }
} else {
    echo "Элемент с таким ID не найден.";
}
?>

2. Как получить раздел инфоблока по коду (символьному коду) элемента

Здесь принцип тот же, только на первом этапе мы используем фильтр по CODE.

Старый метод (через CIBlockElement и CIBlockSection)

Шаги:

  1. Использовать CIBlockElement::GetList с фильтром по CODE (и, при необходимости, по IBLOCK_ID).
  2. Получить поле IBLOCK_SECTION_ID.
  3. По этому ID вызвать CIBlockSection::GetByID.

Пример кода:

<?php
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");

$ELEMENT_CODE = "my-element-code";
$IBLOCK_ID = 5;

$elementRes = CIBlockElement::GetList(
    [],
    [
        "IBLOCK_ID" => $IBLOCK_ID,
        "CODE"      => $ELEMENT_CODE
    ],
    false,
    false,
    ["ID", "NAME", "IBLOCK_SECTION_ID"]
);

if ($elementData = $elementRes->GetNext()) {
    $sectionId = $elementData["IBLOCK_SECTION_ID"];
    if ($sectionId) {
        $sectionRes = CIBlockSection::GetByID($sectionId);
        if ($sectionData = $sectionRes->GetNext()) {
            echo "ID раздела: " . $sectionData["ID"] . "<br>";
            echo "Название раздела: " . $sectionData["NAME"] . "<br>";
            echo "Код раздела: " . $sectionData["CODE"] . "<br>";
        } else {
            echo "Раздел не найден.";
        }
    } else {
        echo "У элемента нет основного раздела.";
    }
} else {
    echo "Элемент с таким кодом не найден.";
}
?>

Новый метод (D7, через ElementTable и SectionTable)

  1. Получаем элемент по его символьному коду.
  2. Извлекаем IBLOCK_SECTION_ID.
  3. Запрашиваем информацию о разделе.

Пример кода:

<?php
use Bitrix\Main\Loader;
use Bitrix\Iblock\ElementTable;
use Bitrix\Iblock\SectionTable;

require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");

Loader::includeModule("iblock");

$ELEMENT_CODE = "my-element-code";
$IBLOCK_ID = 5;

// Находим элемент по коду
$element = ElementTable::getList([
    "filter" => [
        "=IBLOCK_ID" => $IBLOCK_ID,
        "=CODE"      => $ELEMENT_CODE
    ],
    "select" => ["ID", "IBLOCK_SECTION_ID"]
])->fetch();

if ($element) {
    $sectionId = $element['IBLOCK_SECTION_ID'];
    if ($sectionId) {
        $section = SectionTable::getList([
            "filter" => ["=ID" => $sectionId],
            "select" => ["ID", "NAME", "CODE"]
        ])->fetch();

        if ($section) {
            echo "ID раздела: " . $section["ID"] . "<br>";
            echo "Название раздела: " . $section["NAME"] . "<br>";
            echo "Код раздела: " . $section["CODE"] . "<br>";
        } else {
            echo "Раздел не найден.";
        }
    } else {
        echo "У элемента нет основного раздела.";
    }
} else {
    echo "Элемент с таким кодом не найден.";
}
?>

3. Как получить все разделы элемента инфоблока

В 1С-Битрикс элемент может принадлежать сразу нескольким разделам (при включённой множественной привязке). Чтобы получить все разделы, используем:

Старый метод (через CIBlockElement::GetElementGroups)

Пример кода:

<?php
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");

$ELEMENT_ID = 123;

// Получаем все разделы элемента
$sectionRes = CIBlockElement::GetElementGroups($ELEMENT_ID, true, ["ID", "NAME", "CODE", "IBLOCK_SECTION_ID", "DEPTH_LEVEL"]);
while ($sectionData = $sectionRes->Fetch()) {
    echo "ID раздела: " . $sectionData["ID"] . "<br>";
    echo "Название раздела: " . $sectionData["NAME"] . "<br>";
    echo "Код раздела: " . $sectionData["CODE"] . "<br>";
    echo "Родительский раздел: " . $sectionData["IBLOCK_SECTION_ID"] . "<br>";
    echo "Уровень вложенности: " . $sectionData["DEPTH_LEVEL"] . "<br>";
    echo "<hr>";
}
?>

Новый метод (D7, через SectionElementTable и SectionTable)

Чтобы «по-новому» получить все разделы, к которым привязан элемент, можно обратиться к таблице b_iblock_section_element через ORM-класс Bitrix\Iblock\SectionElementTable.

  1. Находим записи, где IBLOCK_ELEMENT_ID равно нужному элементу.
  2. Извлекаем IBLOCK_SECTION_ID каждой записи.
  3. Для каждого IBLOCK_SECTION_ID делаем запрос в SectionTable::getList() (или используем join).

Пример кода:

<?php
use Bitrix\Main\Loader;
use Bitrix\Iblock\SectionElementTable;
use Bitrix\Iblock\SectionTable;

require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");

Loader::includeModule("iblock");

$ELEMENT_ID = 123;

$sections = SectionElementTable::getList([
    'filter' => [
        '=IBLOCK_ELEMENT_ID' => $ELEMENT_ID
    ],
    'select' => ['IBLOCK_SECTION_ID']
]);

while ($sectionItem = $sections->fetch()) {
    $sectionId = $sectionItem['IBLOCK_SECTION_ID'];

    // Теперь берём данные раздела
    $sectionData = SectionTable::getList([
        'filter' => ['=ID' => $sectionId],
        'select' => ['ID', 'NAME', 'CODE', 'IBLOCK_SECTION_ID', 'DEPTH_LEVEL']
    ])->fetch();

    if ($sectionData) {
        echo "ID раздела: " . $sectionData["ID"] . "<br>";
        echo "Название раздела: " . $sectionData["NAME"] . "<br>";
        echo "Код раздела: " . $sectionData["CODE"] . "<br>";
        echo "Родительский раздел: " . $sectionData["IBLOCK_SECTION_ID"] . "<br>";
        echo "Уровень вложенности: " . $sectionData["DEPTH_LEVEL"] . "<br>";
        echo "<hr>";
    }
}
?>

4. Как получить корневой раздел элемента инфоблока

Корневым разделом обычно называют верхний «предок» в иерархии разделов (уровень DEPTH_LEVEL = 1 или раздел, у которого IBLOCK_SECTION_ID = 0). Если элемент привязан к нескольким веткам — значит может быть несколько корневых разделов.

Старый метод (цепочечная итерация)

  1. Получить (все) раздел(ы), к которым привязан элемент.
  2. Для каждого раздела «подниматься» по цепочке родительских ID через CIBlockSection::GetByID.
  3. Когда у раздела IBLOCK_SECTION_ID = 0, он является корневым.

Пример кода:

<?php
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");

$ELEMENT_ID = 123;

// Шаг 1. Найдём все разделы элемента
$sectionRes = CIBlockElement::GetElementGroups($ELEMENT_ID, true, ["ID", "IBLOCK_SECTION_ID", "NAME"]);
while ($sectionData = $sectionRes->Fetch()) {
    $currentSectionId = $sectionData["ID"];
    $rootSectionId = $currentSectionId;
    $rootSectionName = $sectionData["NAME"];

    // Шаг 2. Поднимаемся по цепочке родительских разделов
    while (true) {
        $parentRes = CIBlockSection::GetByID($currentSectionId);
        if ($parentData = $parentRes->GetNext()) {
            // Проверяем, есть ли родитель
            if ($parentData["IBLOCK_SECTION_ID"] > 0) {
                $currentSectionId = $parentData["IBLOCK_SECTION_ID"];
            } else {
                // Мы дошли до корня
                $rootSectionId = $parentData["ID"];
                $rootSectionName = $parentData["NAME"];
                break;
            }
        } else {
            // Раздел не найден — прерываем
            break;
        }
    }

    echo "Элемент принадлежит корневому разделу ID = " . $rootSectionId
       . ", название = " . $rootSectionName . "<br>";
}
?>

Новый метод (D7, через SectionTable)

Логика аналогична: получаем ID всех разделов, дальше движемся по родителям. Только вместо CIBlockSection::GetByID используем SectionTable::getList.

  1. Сначала находите все IBLOCK_SECTION_ID, к которым привязан элемент (через SectionElementTable).
  2. Для каждого найденного раздела делаете цикл: пока IBLOCK_SECTION_ID != 0, идём вверх.
  3. Как только находим раздел, у которого IBLOCK_SECTION_ID = 0, — это и есть корневой.

Упрощённый пример (без учёта множественных разделов, показываем на одном основном разделе элемента):

<?php
use Bitrix\Main\Loader;
use Bitrix\Iblock\ElementTable;
use Bitrix\Iblock\SectionTable;

require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");
Loader::includeModule("iblock");

$ELEMENT_ID = 123;

// Получим основной раздел элемента (если он один)
$element = ElementTable::getList([
    'filter' => ['=ID' => $ELEMENT_ID],
    'select' => ['IBLOCK_SECTION_ID']
])->fetch();

if ($element && $element['IBLOCK_SECTION_ID']) {
    $currentSectionId = $element['IBLOCK_SECTION_ID'];
    $rootSectionId = null;
    $rootSectionName = null;

    while ($currentSectionId) {
        $section = SectionTable::getList([
            'filter' => ['=ID' => $currentSectionId],
            'select' => ['ID', 'NAME', 'IBLOCK_SECTION_ID']
        ])->fetch();

        if ($section) {
            if ($section['IBLOCK_SECTION_ID'] > 0) {
                // поднимаемся выше
                $currentSectionId = $section['IBLOCK_SECTION_ID'];
            } else {
                // корневой раздел
                $rootSectionId = $section['ID'];
                $rootSectionName = $section['NAME'];
                break;
            }
        } else {
            break;
        }
    }

    if ($rootSectionId) {
        echo "Корневой раздел ID: " . $rootSectionId . ", Название: " . $rootSectionName;
    } else {
        echo "Не удалось определить корневой раздел.";
    }
} else {
    echo "Элемент не найден или у него нет основного раздела.";
}
?>

Если элемент может быть в нескольких разделах, аналогично перебираем все и ищем корневые для каждого.


Заключение

Работа с разделами в 1С-Битрикс — одна из базовых задач при создании каталогов, новостных порталов, блогов, интернет-магазинов и других проектов на инфоблоках.

  • Старое ядро: Используем классы CIBlockElement и CIBlockSection.
  • D7 (ORM): Применяем ElementTable, SectionTable и в случае множественной привязки — SectionElementTable.

Основные приёмы:

  1. Получение основного раздела: достаточно посмотреть поле IBLOCK_SECTION_ID у элемента.
  2. Получение всех разделов: использовать CIBlockElement::GetElementGroups (старое ядро) или SectionElementTable (новое ядро).
  3. Корневой раздел: «подниматься» по цепочке через IBLOCK_SECTION_ID, пока не дойдёте до раздела, у которого IBLOCK_SECTION_ID = 0.

Правильное понимание этих механизмов позволит вам эффективно управлять контентом, навигацией и структурой вашего сайта на 1С-Битрикс. Если у вас остались вопросы, смело задавайте их в комментариях или обращайтесь к официальной документации по инфоблокам — там вы найдёте дополнительные подробности и нюансы.

Теги:  Битрикс, рецепты, D7

Интернет-магазин от 120 000 руб., срок от 4 недель

Платформа для продажи товаров или услуг. Включает интерактивные формы обратной связи в каждой карточке товара, а также множество статичных и динамичных разделов.

Корпоративный сайт от 60 000 руб., срок от 3 недель

Готовый информационный ресурс, включающий лицензию на 1С-Битрикс «Стандарт», технологию «Композитный сайт».

Лендинг от 25 000 руб., срок от 2 недель

Компактный сайт, идеально подходящий для старта. На одной странице можно представить ключевые преимущества вашей компании и разместить форму для обратной связи.