Вывод данных из инфоблока с помощью API Битрикс

Alexander K.
1С-Bitrix
19.09.2017
135

Битрикс имеет крайне проработанный механизм доступа к данным через API. С помощью огромного количества методов и функций, включенных в ядро D7, веб-разработчик может провести практические любые операции с данным, не изобретая велосипед заново. Отличным примером использования этих возможностей является работа с информационными блоками через API. А одна из наиболее часто встречающихся задач - вывод данных из элементов инфоблока через стандартные функции.

Например, выполняя очередной проект с сайтом, мне требовалось вывести детальную страницу инфоблока с информацией через API. Необходимость в этом возникла, когда заказчику потребовалось привязать к каждому элементу собственный список новостей (то есть ещё один список элементов). В целом, данная задача решается относительно просто через вызов компонента "Детальная страница". Но тут был ещё один нюанс: на каждую детальную страницу, помимо списка новостей, должна крепиться форма анкеты/опроса. После этого, я однозначно решил не использовать стандартные компоненты, а обратиться непосредственно к API Битрикса (как впоследствии оказалось - не зря, ибо потом всплыли более сложные "хотелки" заказчика).

Итак, приступим.

Выводим свойства элемента через API

Для начала рассмотрим весь код вызова:
<?
CModule::IncludeModule("iblock"); // Подключаем модуль iblock 
$arSelect = Array("ID", "SEARCHABLE_CONTENT", "NAME", "PREVIEW_PICTURE", "DETAIL_PICTURE", "PROPERTY_код_свойства"); // Указываем список параметров, которые будем использовать
$arFilter = Array("IBLOCK_ID"=номер_id_блока_с_элементами, "ID"=array(номер_элемента), "ACTIVE"="Y"); // Указываем параметры фильтра, по которым будем выводить элементы
$res = CIBlockElement::GetList(Array("SORT"="ASC"), $arFilter, false, false, $arSelect); // Вызов
while($ob = $res->GetNextElement())
	{$arFields = $ob->GetFields();?>
		HTML код и вызов свойств
	<?};?>
Теперь сделаем тоже самое, но со всеми заполненными полями. Допустим, нам нужно вывести данные из инфоблока с ID = 17 значения свойств элемента с ID = 4257. Будем выводить название элемента, ссылку на картинку и одно пользовательское свойство с кодом YEARS (тип: строка). Все это дело будет выглядеть вот так:
<?
CModule::IncludeModule("iblock");
$arSelect = Array("ID", "NAME", "PREVIEW_PICTURE", "PROPERTY_YEARS");
$arFilter = Array("IBLOCK_ID"=17, "ID"=array(4257), "ACTIVE"="Y");
$res = CIBlockElement::GetList(Array("SORT"="ASC"), $arFilter, false, false, $arSelect);
while($ob = $res->GetNextElement())
	{$arFields = $ob->GetFields();?>
		Выводим название элемента: <?echo $arFields["NAME"];?> <br>
		Выводим свойство с кодом YEARS: <?echo $arFields["PROPERTY_YEARS_VALUE"];?> <br>
		Выводим ссылку на картинку: <?echo CFile::GetPath($arFields["PREVIEW_PICTURE"]);?> 
	<?};?>
Важно уточнить, что различные типы пользовательских свойств выводятся по разному. Ниже представлены возможные варианты:
<?
// вывод названия новости
echo $arFields["NAME"];

// вывод детального текста элемента
echo $arFields["DETAIL_TEXT"];

// получить путь к изображению
echo CFile::GetPath($arFields["PREVIEW_PICTURE"]);

// получить путь к файлу (пользовательское свойство типа файл)
echo CFile::GetPath($arFields["PROPERTY_FILE_VALUE"]);

// вывод пользовательского свойства (тип строка, число, список, дата, привязка к элементу и т.д.)
echo $arFields["PROPERTY_PROP_VALUE"];

// вывод значения свойства типа HTML/Текст
$arInfo = (htmlspecialcharsBack($arFields["PROPERTY_PROP_VALUE"]));
echo $arInfo["TEXT"];
;?>

Всё это время мы рассматривали простые пользовательские свойства. А что будет, если эти самые свойства сделать множественными? А будет всё куда занимательнее, т.к. все свойства у нас выводятся в цикле while.

Если хоть одно свойство из перечня $arSelect = Array() будет иметь множественное заполненное значение, весь код внутри while отразится столько раз, сколько дополнительных полей было заполнено в этом множественном свойстве.

Решением проблемы может стать ещё один вызов метода, специально для этого множественного свойства. Это можно сделать даже внутри первого вызова (например, в случае, если первый вызов охватывает весь контент страницы).