Построитель запросов ORM
Методы выборки getList сразу выполняют запросы и возвращают результаты. Они подходят для простых запросов, но неудобны если параметры неизвестны заранее или нужна сложная логика.
Гибкость с Bitrix\Main\Entity\Query. Для гибкой настройки запросов используйте объект Bitrix\Main\Entity\Query. Он накапливает параметры для запроса. Это полезно, когда параметры неизвестны заранее и формируются программно.
Пример с getList:
$result = BookTable::getList([
'select' => ['ISBN', 'TITLE', 'PUBLISH_DATE'],
'filter' => ['=ID' => 1]
]);
Аналогичный пример с Bitrix\Main\Entity\Query:
$q = new Bitrix\Main\Entity\Query(BookTable::getEntity());
$q->setSelect(['ISBN', 'TITLE', 'PUBLISH_DATE']);
$q->setFilter(['=ID' => 1]);
$result = $q->exec();
Объект Bitrix\Main\Entity\Query ключевой элемент для выборки данных и используется внутри getList. Однако переопределение методов getList может быть ограничено, метод может сработать при вызове, но не через Bitrix\Main\Entity\Query.
Постепенное добавление параметров
Если вы не знаете заранее, какие поля выбрать или какие фильтры применить, используйте объект Bitrix\Main\Entity\Query для постепенного добавления параметров.
$query = new Bitrix\Main\Entity\Query(BookTable::getEntity());
attachSelect($query);
attachOthers($query);
$result = $query->exec();
// Функция для добавления полей в запрос
function attachSelect(Bitrix\Main\Entity\Query $query): void
{
$query->addSelect('ID');
// Условие для добавления поля ISBN
if (/* условие */) {
$query->addSelect('ISBN');
}
}
function attachOthers(Bitrix\Main\Entity\Query $query): void
{
// Условие для добавления фильтра
if (/* условие */) {
$query->setFilter(/* параметры фильтра */);
}
// Условие для добавления сортировки
if (/* условие */) {
$query->setOrder(/* параметры сортировки */);
}
}
Создание объекта Query
Используем new Bitrix\Main\Entity\Query(BookTable::getEntity()) для создания нового объекта Query, связанного с сущностью BookTable. Это будет основой для построения запроса.
Добавление полей в запрос
Функция attachSelect добавляет поля, которые нужно выбрать из базы данных.
addSelect('ID')добавляет полеIDв список выбираемых полей- Условие внутри функции добавляет поле
ISBN, если оно необходимо
Добавление фильтров и сортировки
Функция attachOthers добавляет фильтры и сортировку.
setFilterустанавливает условия фильтрации данныхsetOrderзадает порядок сортировки результатов
Запрос без выполнения
Объект Bitrix\Main\Entity\Query позволяет строить запрос без его выполнения. Это полезно для подзапросов или получения текста запроса:
$q = new Bitrix\Main\Entity\Query(BookTable::getEntity());
$q->setSelect(['ID']);
$q->setFilter(['=PUBLISH_DATE' => new Type\Date('2014-12-13', 'Y-m-d')]);
$sql = $q->getQuery();
file_put_contents('/tmp/today_books.sql', $sql);
// Запрос "SELECT ID FROM my_book WHERE PUBLISH_DATE='2014-12-31'" будет сохранен в файл, но не выполнен.
Доступные методы
Список методов Bitrix\Main\Entity\Query:
Получение данных
setSelect(),setGroup()устанавливает массив с именами полейaddSelect(),addGroup()добавляет имя поляgetSelect(),getGroup()возвращает массив с именами полей
Фильтрация данных
setFilter()устанавливает одно или многомерный массив с описанием фильтраaddFilter()добавляет один параметр фильтра со значениемgetFilter()возвращает текущее описание фильтра
Сортировка данных
setOrder()устанавливает массив с именами полей и порядком сортировкиaddOrder()добавляет одно поле с порядком сортировкиgetOrder()возвращает текущее описание сортировки
Ограничение количества данных
setLimit(),setOffset()устанавливает значениеgetLimit(),getOffset()возвращает текущее значение
Временное поле
registerRuntimeField()регистрирует новое временное поле для исходной сущности
С какими сущностями работает построитель запросов
Всё что написано ниже, применимо и к другим модулям, только названия таблиц будут другие. Многое можно узнать из файла /bitrix/modules/main/lib/orm/data/datamanager.php
Подключаем модуль:
\Bitrix\Main\Loader::includeModule('iblock');
После подключения модуля, нам становится доступен целый набор различных классов и методов для работы с данными инфоблоков. Существуют и другие методы для работы с инфоблоками, и это лишь часть из них. Наиболее часто используемые методы, это получение списков записей:
\Bitrix\Iblock\TypeTable::getEntity();типы инфоблоков\Bitrix\Iblock\IblockTable::getEntity();инфоблоки\Bitrix\Iblock\PropertyTable::getEntity();свойства инфоблоков\Bitrix\Iblock\PropertyEnumerationTable::getEntity();значения свойств, например списков\Bitrix\Iblock\SectionTable::getEntity();разделы инфоблоков\Bitrix\Iblock\ElementTable::getEntity();элементы инфоблоков\Bitrix\Iblock\InheritedPropertyTable::getEntity();наследуемые свойства, seo шаблоны
Автоматическая генерация класса
Для использования генератора ORM классов перейдите на страницу Настройки -> Настройки продукта -> Настройки модулей -> Монитор производительности модуль Монитор производительности должен быть установлен. На вкладке Генератор таблетов отметьте поле Разрешить генерацию таблетов для ORM.
Автоматически сгенерировать класс с описанием любой таблицы можно на странице Настройки -> Производительность -> Таблицы, в меню действий доступен пункт ORM
Выборка
Выбираем элементы инфоблока с идентификатором 5:
Bitrix\Main\Loader::includeModule('iblock');
// создаем объект Query, в качестве параметра передаем объект сущности (элемент инфоблока)
$query = new Bitrix\Main\Entity\Query(
Bitrix\Iblock\ElementTable::getEntity()
);
// выбираем идентификатор элемента, символьный код и наименование
$query->setSelect(array('ID', 'CODE', 'NAME'))
// идентификатор инфоблока равен 5
->setFilter(array('IBLOCK_ID' => 5))
// сортируем элементы по идентификатору, по возрастанию
->setOrder(array('ID' => 'ASC'))
// выбираем только три элемента
->setLimit(3);
// посмотрим, какой запрос был сформирован
echo '<pre>' . $query->getQuery() . '</pre>';
// выполняем запрос
$result = $query->exec();
// выводим результат
while ($row = $result->fetch()) {
pp($row);
}
Запрос:
SELECT
`iblock_element`.`ID` AS `ID`,
`iblock_element`.`CODE` AS `CODE`,
`iblock_element`.`NAME` AS `NAME`
FROM
`b_iblock_element` `iblock_element`
WHERE
`iblock_element`.`IBLOCK_ID` = 5
ORDER BY
`ID` ASC
LIMIT
0, 3
Ответ:
Array
(
[ID] => 347
[CODE] => angliyskiy-buldog
[NAME] => Английский бульдог
)
Array
(
[ID] => 348
[CODE] => dalmatin
[NAME] => Далматин
)
Array
(
[ID] => 349
[CODE] => afganskaya-borzaya
[NAME] => Афганская борзая
)
Соединение
Например через сущность ElementTable, можно выбирать или ставить условия на поля связанной сущности, в данном примере это IBLOCK. Связанная таблица по умолчанию присоединяется с помощью LEFT JOIN. Вспомним reference поле IBLOCK в описании ElementTable:
'IBLOCK' => array(
'data_type' => 'Bitrix\Iblock\Iblock',
'reference' => array('=this.IBLOCK_ID' => 'ref.ID'),
)
Выберем данные самого инфоблока вместе с элементами инфоблока:
Bitrix\Main\Loader::includeModule('iblock');
// создаем объект Query, в качестве параметра передаем объект сущности (элемент инфоблока)
$query = new Bitrix\Main\Entity\Query(
Bitrix\Iblock\ElementTable::getEntity()
);
// выборка
$query->setSelect(array('ID', 'CODE', 'NAME', 'IBLOCK.ID', 'IBLOCK.CODE', 'IBLOCK.NAME'))
// за место этого
// ->setFilter(array('IBLOCK_ID' => 5))
// можно так
->setFilter(array('IBLOCK.ID' => 5))
// сортировка
->setOrder(array('ID' => 'ASC'))
// лимит
->setLimit(3);
// посмотрим, какой запрос был сформирован
echo '<pre>' . $query->getQuery() . '</pre>';
// выполняем запрос
$result = $query->exec();
// выводим результат
while ($row = $result->fetch()) {
pp($row);
}
Запрос:
SELECT
`iblock_element`.`ID` AS `ID`,
`iblock_element`.`CODE` AS `CODE`,
`iblock_element`.`NAME` AS `NAME`,
`iblock_element_iblock`.`ID` AS `IBLOCK_ELEMENT_IBLOCK_ID`,
`iblock_element_iblock`.`CODE` AS `IBLOCK_ELEMENT_IBLOCK_CODE`,
`iblock_element_iblock`.`NAME` AS `IBLOCK_ELEMENT_IBLOCK_NAME`
FROM
`b_iblock_element` `iblock_element` LEFT JOIN `b_iblock` `iblock_element_iblock`
ON `iblock_element`.`IBLOCK_ID` = `iblock_element_iblock`.`ID`
WHERE
`iblock_element_iblock`.`ID` = 5
ORDER BY
`ID` ASC
LIMIT
0, 3
Ответ:
Array
(
[ID] => 347
[CODE] => angliyskiy-buldog
[NAME] => Английский бульдог
[IBLOCK_ELEMENT_IBLOCK_ID] => 5
[IBLOCK_ELEMENT_IBLOCK_CODE] => articles
[IBLOCK_ELEMENT_IBLOCK_NAME] => Статьи о домашних животных
)
Array
(
[ID] => 348
[CODE] => dalmatin
[NAME] => Далматин
[IBLOCK_ELEMENT_IBLOCK_ID] => 5
[IBLOCK_ELEMENT_IBLOCK_CODE] => articles
[IBLOCK_ELEMENT_IBLOCK_NAME] => Статьи о домашних животных
)
Array
(
[ID] => 349
[CODE] => afganskaya-borzaya
[NAME] => Афганская борзая
[IBLOCK_ELEMENT_IBLOCK_ID] => 5
[IBLOCK_ELEMENT_IBLOCK_CODE] => articles
[IBLOCK_ELEMENT_IBLOCK_NAME] => Статьи о домашних животных
)
Соединение со сложной логикой
В определении runtime-reference поля можно указывать тип соединения LEFT, RIGHT, INNER, в фильтре использовать сложную логику, как в CIblockElement::GetList():
Bitrix\Main\Loader::includeModule('iblock');
// создаем объект Query, в качестве параметра передаем объект сущности (инфоблок)
$query = new Bitrix\Main\Entity\Query(
Bitrix\Iblock\IblockTable::getEntity()
);
// регистрируем новое временное поле для исходной сущности
$query->registerRuntimeField(
// поле element как ссылка на таблицу b_iblock_element
'element',
array(
// тип — сущность ElementTable
'data_type' => 'Bitrix\Iblock\ElementTable',
// this.ID относится к таблице, относительно которой строится запрос, т.е. b_iblock.ID = b_iblock_element.IBLOCK_ID
'reference' => array('=this.ID' => 'ref.IBLOCK_ID'),
// тип соединения INNER JOIN
'join_type' => 'INNER'
)
);
// регистрируем новое временное поле для исходной сущности
$query->registerRuntimeField(
// поле type как ссылка на таблицу b_iblock_type
'type',
array(
'data_type' => 'Bitrix\Iblock\TypeTable',
'reference' => array('=this.IBLOCK_TYPE_ID' => 'ref.ID'),
'join_type' => 'INNER'
)
);
// выбираем название инфоблока, символьный код инфоблока, название элемента, символьный код элемента и идентификатор типа инфоблока
$query->setSelect(array('NAME', 'CODE', 'element.NAME', 'element.CODE', 'type.ID'));
// выбираем элементы с идентификаторами 348 или 349
$query->setFilter(
array(
'LOGIC' => 'OR',
array('element.ID' => 348),
array('element.ID' => 349),
)
);
// посмотрим, какой запрос был сформирован
echo '<pre>' . $query->getQuery() . '</pre>';
// выполняем запрос
$result = $query->exec();
// выводим результат
while ($row = $result->fetch()) {
pp($row);
}
Запрос:
SELECT
`iblock_iblock`.`NAME` AS `NAME`,
`iblock_iblock`.`CODE` AS `CODE`,
`iblock_iblock_element`.`NAME` AS `IBLOCK_IBLOCK_element_NAME`,
`iblock_iblock_element`.`CODE` AS `IBLOCK_IBLOCK_element_CODE`,
`iblock_iblock_type`.`ID` AS `IBLOCK_IBLOCK_type_ID`
FROM
`b_iblock` `iblock_iblock`
INNER JOIN `b_iblock_element` `iblock_iblock_element`
ON `iblock_iblock`.`ID` = `iblock_iblock_element`.`IBLOCK_ID`
INNER JOIN `b_iblock_type` `iblock_iblock_type`
ON `iblock_iblock`.`IBLOCK_TYPE_ID` = `iblock_iblock_type`.`ID`
WHERE
(`iblock_iblock_element`.`ID` = 348) OR (`iblock_iblock_element`.`ID` = 349)
Ответ:
Array
(
[NAME] => Статьи о домашних животных
[CODE] => articles
[IBLOCK_IBLOCK_element_NAME] => Далматин
[IBLOCK_IBLOCK_element_CODE] => dalmatin
[IBLOCK_IBLOCK_type_ID] => content
)
Array
(
[NAME] => Статьи о домашних животных
[CODE] => articles
[IBLOCK_IBLOCK_element_NAME] => Афганская борзая
[IBLOCK_IBLOCK_element_CODE] => afganskaya-borzaya
[IBLOCK_IBLOCK_type_ID] => content
)
Агрегатные функции
В запросах можно использовать агрегатные функции MySQL. Для это служит метод registerRuntimeField(), регистрирующий новое поле на время выполнения запроса. Посмотрим, сколько активных элементов в инфоблоке:
Bitrix\Main\Loader::includeModule('iblock');
// создаем объект Query, в качестве параметра передаем объект сущности (элемент инфоблока)
$query = new Bitrix\Main\Entity\Query(
Bitrix\Iblock\ElementTable::getEntity()
);
// регистрируем новое временное поле для исходной сущности
$query->registerRuntimeField(
'ACTIVE_ELEMENTS',
array(
// тип вычисляемого поля
'data_type' => 'string',
// агрегатная функция (COUNT, MAX, MIN, SUM, AVG) и поле для подстановки
'expression' => array('GROUP_CONCAT(%s)', 'NAME')
)
);
// выборка
$query->setSelect(array('IBLOCK.NAME', 'ACTIVE_ELEMENTS'));
// фильтр
$query->setFilter(array('IBLOCK.ID' => 5, '=ACTIVE' => 'Y'));
// посмотрим, какой запрос был сформирован
echo '<pre>' . $query->getQuery() . '</pre>';
// выполняем запрос
$result = $query->exec();
// выводим результат
while ($row = $result->fetch()) {
pp($row);
}
Запрос:
SELECT
`iblock_element_iblock`.`NAME` AS `IBLOCK_ELEMENT_IBLOCK_NAME`,
GROUP_CONCAT(`iblock_element`.`NAME`) AS `ACTIVE_ELEMENTS`
FROM
`b_iblock_element` `iblock_element` LEFT JOIN `b_iblock` `iblock_element_iblock`
ON `iblock_element`.`IBLOCK_ID` = `iblock_element_iblock`.`ID`
WHERE
`iblock_element_iblock`.`ID` = 5 AND `iblock_element`.`ACTIVE` = 'Y'
GROUP BY
`iblock_element_iblock`.`NAME`
Ответ:
Array
(
[IBLOCK_ELEMENT_IBLOCK_NAME] => Статьи о домашних животных
[ACTIVE_ELEMENTS] => Английский бульдог,Далматин,Афганская борзая,Абиссинская кошка,Сиамская кошка,Американский бобтейл,Британская короткошерстная,Лабрадор,Лайка
)
Подсчет
Выбираем разделы инфоблока с идентифкатором 5 и подсчитываем количество элементов в каждом, учитываем только активные разделы и элементы:
Bitrix\Main\Loader::includeModule('iblock');
// создаем объект Query, в качестве параметра передаем объект сущности (элемент инфоблока)
$query = new Bitrix\Main\Entity\Query(
Bitrix\Iblock\ElementTable::getEntity()
);
// регистрируем новое временное поле для исходной сущности
$query->registerRuntimeField(
'ELEMENT_COUNT',
array(
// тип вычисляемого поля
'data_type' => 'integer',
// агрегатная функция (COUNT, MAX, MIN, SUM, AVG) и поле для подстановки
'expression' => array('COUNT(%s)', 'NAME')
)
);
// регистрируем новое временное поле для исходной сущности
$query->registerRuntimeField(
'ELEMENT_LIST',
array(
// тип вычисляемого поля
'data_type' => 'string',
// агрегатная функция (COUNT, MAX, MIN, SUM, AVG) и поле для подстановки
'expression' => array('GROUP_CONCAT(%s)', 'NAME')
)
);
// выборка
$query->setSelect(array('IBLOCK_SECTION.NAME', 'ELEMENT_COUNT', 'ELEMENT_LIST'));
// учитываем только активные разделы и активные элементы
$query->setFilter(array('=ACTIVE' => 'Y', '=IBLOCK_SECTION.ACTIVE' => 'Y'));
// выбираем только разделы инфоблока с идентификатором 5
$query->addFilter('IBLOCK.ID', 5);
// посмотрим, какой запрос был сформирован
echo '<pre>' . $query->getQuery() . '</pre>';
// выполняем запрос
$result = $query->exec();
// выводим результат
while ($row = $result->fetch()) {
pp($row);
}
Запрос:
SELECT
`iblock_element_iblock_section`.`NAME` AS `IBLOCK_ELEMENT_IBLOCK_SECTION_NAME`,
COUNT(`iblock_element`.`NAME`) AS `ELEMENT_COUNT`,
GROUP_CONCAT(`iblock_element`.`NAME`) AS `ELEMENT_LIST`
FROM
`b_iblock_element` `iblock_element`
LEFT JOIN `b_iblock_section` `iblock_element_iblock_section`
ON `iblock_element`.`IBLOCK_SECTION_ID` = `iblock_element_iblock_section`.`ID`
LEFT JOIN `b_iblock` `iblock_element_iblock`
ON `iblock_element`.`IBLOCK_ID` = `iblock_element_iblock`.`ID`
WHERE
`iblock_element`.`ACTIVE` = 'Y' AND
`iblock_element_iblock_section`.`ACTIVE` = 'Y' AND
`iblock_element_iblock`.`ID` = 5
GROUP BY
`iblock_element_iblock_section`.`NAME`
Ответ:
Array
(
[IBLOCK_ELEMENT_IBLOCK_SECTION_NAME] => Породы кошек
[ELEMENT_COUNT] => 4
[ELEMENT_LIST] => Абиссинская кошка,Сиамская кошка,Американский бобтейл,Британская короткошерстная
)
Array
(
[IBLOCK_ELEMENT_IBLOCK_SECTION_NAME] => Породы собак
[ELEMENT_COUNT] => 3
[ELEMENT_LIST] => Английский бульдог,Далматин,Афганская борзая
)
Array
(
[IBLOCK_ELEMENT_IBLOCK_SECTION_NAME] => Служебные породы
[ELEMENT_COUNT] => 2
[ELEMENT_LIST] => Лабрадор,Лайка
)
Добавим еще одно условие, чтобы выбирать только разделы, содержащие более трех элементов:
$query->addFilter('>ELEMENT_COUNT', 3);
Запрос:
SELECT
`iblock_element_iblock_section`.`NAME` AS `IBLOCK_ELEMENT_IBLOCK_SECTION_NAME`,
COUNT(`iblock_element`.`NAME`) AS `ELEMENT_COUNT`,
GROUP_CONCAT(`iblock_element`.`NAME`) AS `ELEMENT_LIST`
FROM
`b_iblock_element` `iblock_element`
LEFT JOIN `b_iblock_section` `iblock_element_iblock_section`
ON `iblock_element`.`IBLOCK_SECTION_ID` = `iblock_element_iblock_section`.`ID`
LEFT JOIN `b_iblock` `iblock_element_iblock`
ON `iblock_element`.`IBLOCK_ID` = `iblock_element_iblock`.`ID`
WHERE
`iblock_element`.`ACTIVE` = 'Y' AND
`iblock_element_iblock_section`.`ACTIVE` = 'Y' AND
`iblock_element_iblock`.`ID` = 5
GROUP BY
`iblock_element_iblock_section`.`NAME`
HAVING
COUNT(`iblock_element`.`NAME`) > 3
Ответ:
Array
(
[IBLOCK_ELEMENT_IBLOCK_SECTION_NAME] => Породы кошек
[ELEMENT_COUNT] => 4
[ELEMENT_LIST] => Абиссинская кошка,Сиамская кошка,Американский бобтейл,Британская короткошерстная
)
Ссылка на другую сущность
Runtime поле может быть не только вычисляемым значением, но и ссылкой на другую сущность. Т.е. в методе getMap() можно не описывать связь, а сформировать ее прямо в запросе. Например, создадим объект Query для сущности IblockTable, свяжем ее с ElementTable и выберем элемент с ID=349:
Bitrix\Main\Loader::includeModule('iblock');
// создаем объект Query, в качестве параметра передаем объект сущности (инфоблок)
$query = new Bitrix\Main\Entity\Query(
Bitrix\Iblock\IblockTable::getEntity()
);
// регистрируем новое временное поле для исходной сущности
$query->registerRuntimeField(
// поле element как ссылка на таблицу b_iblock_element
'element',
array(
// тип — сущность ElementTable
'data_type' => 'Bitrix\Iblock\ElementTable',
// this.ID относится к таблице, относительно которой строится запрос, т.е. b_iblock.ID = b_iblock_element.IBLOCK_ID
'reference' => array('=this.ID' => 'ref.IBLOCK_ID'),
)
);
// выбираем название элемента, символьный код, краткое описание, кол-во просмотров и название инфоблока
$query->setSelect(array('element.NAME', 'element.CODE', 'element.PREVIEW_TEXT', 'element.SHOW_COUNTER', 'NAME'));
// выбираем только элемент с идентификатором 349
$query->setFilter(array('element.ID' => 349));
// посмотрим, какой запрос был сформирован
echo '<pre>' . $query->getQuery() . '</pre>';
// выполняем запрос
$result = $query->exec();
// выводим результат
while ($row = $result->fetch()) {
pp($row);
}
Запрос:
SELECT
`iblock_iblock_element`.`NAME` AS `IBLOCK_IBLOCK_element_NAME`,
`iblock_iblock_element`.`CODE` AS `IBLOCK_IBLOCK_element_CODE`,
`iblock_iblock_element`.`PREVIEW_TEXT` AS `IBLOCK_IBLOCK_element_PREVIEW_TEXT`,
`iblock_iblock_element`.`SHOW_COUNTER` AS `IBLOCK_IBLOCK_element_SHOW_COUNTER`,
`iblock_iblock`.`NAME` AS `NAME`
FROM
`b_iblock` `iblock_iblock` LEFT JOIN `b_iblock_element` `iblock_iblock_element`
ON `iblock_iblock`.`ID` = `iblock_iblock_element`.`IBLOCK_ID`
WHERE
`iblock_iblock_element`.`ID` = 349
Ответ:
Array
(
[IBLOCK_IBLOCK_element_NAME] => Афганская борзая
[IBLOCK_IBLOCK_element_CODE] => afganskaya-borzaya
[IBLOCK_IBLOCK_element_PREVIEW_TEXT] => Изящная красавица с длинной развевающейся на бегу шелковистой шерстью...
[IBLOCK_IBLOCK_element_SHOW_COUNTER] => 10
[NAME] => Статьи о домашних животных
)
Пользовательские свойства
Получаем пользовательские свойства элементов инфоблока с идентификатором 5:
Bitrix\Main\Loader::includeModule('iblock');
// создаем объект Query, в качестве параметра передаем объект сущности (свойства)
$query = new Bitrix\Main\Entity\Query(
Bitrix\Iblock\PropertyTable::getEntity()
);
// выборка
$query->setSelect(array('ID', 'NAME', 'CODE', 'PROPERTY_TYPE'));
// фильтр
$query->setFilter(array('IBLOCK_ID' => 5));
// посмотрим, какой запрос был сформирован
echo '<pre>' . $query->getQuery() . '</pre>';
// выполняем запрос
$result = $query->exec();
// выводим результат
while ($row = $result->fetch()) {
pp($row);
}
Запрос:
SELECT
`iblock_property`.`ID` AS `ID`,
`iblock_property`.`NAME` AS `NAME`,
`iblock_property`.`CODE` AS `CODE`,
`iblock_property`.`PROPERTY_TYPE` AS `PROPERTY_TYPE`
FROM
`b_iblock_property` `iblock_property`
WHERE
`iblock_property`.`IBLOCK_ID` = 5
Ответ:
Array
(
[ID] => 47
[NAME] => Автор
[CODE] => AUTHOR
[PROPERTY_TYPE] => S
)
Array
(
[ID] => 48
[NAME] => Оценка
[CODE] => RATING
[PROPERTY_TYPE] => L
)
Array
(
[ID] => 49
[NAME] => Галерея
[CODE] => GALLERY
[PROPERTY_TYPE] => F
)
Array
(
[ID] => 51
[NAME] => Примечание
[CODE] => NOTE
[PROPERTY_TYPE] => S
)

