>
Функции Fetch(), GetNext() и GetNextElement()

Функции Fetch(), GetNext() и GetNextElement()

Волков Михаил Bitrix 12 августа 2019
0 22175
Сложность: Начинающий

На этот раз разберемся с тремя из ларца (из Битрикса), одинаковыми с лица: Fetch(), GetNext() и GetNextElement(). Зачем их три, и чем они друг от друга отличаются.

Введение

Любой запрос к базе данных (БД) с использованием Api Битрикса, будь то GetList(), или GetByID(), или любой другой, в качестве ответа возвращает специальный объект, содержащий данные, выбранные из БД. Этот объект - класс CDBResult, у которого, как и любого другого уважающего себя объекта, есть набор методов, с помощью которых можно обращаться к нему (ссылка на документацию). С помощью этих методов можно узнать количество выбранных записей, получить постраничную навигацию и другие результаты запроса. Однако нас интересуют методы, с помощью которых можно получать непосредственно сами данные из этого объекта. Иначе получать данные из БД и потом не пользоваться ими - все равно что:  "схожу в аптеку за аспирином, но не буду его пить - само пройдет".

Для получения данных из этого объекта есть три метода: Fetch(), GetNext() и GetNextElement(). "Но постойте, - скажете вы, - ведь у объекта CDBResult нет метода GetNextElement()". И вы будете правы. В этой статье мы рассмотрим наследника этого класса, а именно - CIBlockResult.  Выбор пал на него по нескольким причинам: во первых, чаще всего вы будете иметь дело с элементами Инфоблоков, где именно этот объект возвращается при запросе методом GetList().  Во-вторых, рассмотрев более частную реализацию объекта, мы охватим и более общий случай.

Перейдем к знакомству с функциями (это, конечно же, методы). Для того чтобы знать любую функцию в лицо, нужно знать ответ на три вопроса:

  1. Что делает функция?
  2. Что функция возвращает?
  3. Какие параметры функция принимает?

Пролог

Поскольку нам нужно ответить на все три вопроса, а методов всего 3, то получится... дайте посчитать... 3 умножить на 3 - что-то около 9-ти, если не врет мой калькулятор. Кажется, статья будет очень длинной, но нет, ведь эти три метода наследуются друг от друга, а значит, каждый следующий метод лишь расширяет предыдущий. Это заметно сузит объем информации для запоминания. Порядок наследования такой: Fetch() <- GetNext() <- GetNextElement().

Что методы делают?

Fetch

Метод Fetch(), "корень зла" (самый базовый метод), берет очередную строку данных, полученных из БД и возвращает ее в виде ассоциативного массива, сдвигая указатель на следующую запись. Ничего не напоминает? Обычный mysqli_fetch_assoc(). Т.е. делаем цикл и поэлементно получаем данные, выбранные запросом.

GetNext()

Эта функция - обертка вокруг Fetch(), т.е. она делает то же самое, что и Fetch(), и еще кое-что свое. Возвращая массив полей в ассоциативном виде, она преобразует его значения в html-безопасный вид. Помимо этого она создает поля дубликаты с префиксом ~ (тильда), в которых это преобразование не было сделано:

// например из одного поля NAME в массиве получили два
$data = [
'NAME' => 'Функция&nbsp;GetNext',
'~NAME' => 'Функция GetNext'
]

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

И еще одна особенность этого метода, связанная с объектом CIBlockResult, - преобразование шаблонов url-путей (DETAIL_PAGE_URL, SECTION_PAGE_URL и LIST_PAGE_URL), где плейсхолдеры будут заменены реальными значениями из элемента. Таким образом, с помощью этой функции вы получаете реальные ссылки url для выбранных элементов инфоблоков.

GetNextElement()

Эта функция делает то же, что и GetNext(), но возвращает кое-что другое (см. ниже).

Что методы возвращают?

Fetch() и GetNext()

Возвращают либо ассоциативный массив с полями и свойствами выбранного элемента, либо false (если достигнут конца выборки).

GetNextElement()

Возвращает объект _CIBElement. Этот объект содержит дополнительные методы для того, чтобы получить поля элемента и его свойства.

Какие параметры принимают эти методы?

Fetch()

Не принимает никаких параметров.

GetNext() и GetNextElement()

Принимают два параметра:

public function GetNext($bTextHtmlAuto=true$use_tilda=true)
  • Параметр $bTextHtmlAuto (boolean)  указывает, нужно ли производить html-безопасное преобразование.
  • Параметр $use_tilda (boolean) указывает, нужно ли добавлять поля с тильдой (~).

С помощью данных параметров вышеуказанные методы можно приблизить по функциональности к методу Fetch( ), если поставить два раза false.

Итоги

Теперь, досконально зная каждую из трех функций-близнецов, можно определить, когда нужно применять одну, а когда другую.

  • Чаще всего применяйте метод GetNext() для получения html-безопасного вида значений полей и ссылок на страницы элементов или разделов инфоблока.
  • Применяйте метод Fetch(), если вам не нужно ни то, ни другое.
  • Не применяйте метод GetNextElement(), кроме тех случаев, когда вы на 100% уверены, что нужен именно он.

Этот порядок ставит вопрос о том, зачем тогда нужен метод GetNextElement(), и что это за такой 100%-ный случай? Этот метод нужен скорее для максимальный гибкости и настраиваемости, чем для оптимизации и производительности. Он используется в компоненте списка новостей именно для супер-настраиваемости.

Но создавая свой компонент, скорее всего, вы стремитесь к высокой производительности, поэтому в данном случае этот метод не рекомендуется. Причина заключается в том, что для получения свойств вам придется делать дополнительные запросы в БД, а это совсем не к чему.

Эпилог

Раз был пролог, значит нужен и эпилог. На этот раз именно он сыграет роль резюме.

Функция Fetch()

  • Возвращает ассоциативный массив полей и свойств элемента из выборки, сдвигая указатель в ней на следующий элемент. Либо возвращает false, если элементов больше нет.
  • Не принимает никаких параметров.
  • Использовать этот метод следует тогда, когда не нужно html-безопасное преобразование и/или ссылки.

Функция GetNext()

  • Делает то же, что и Fetch(), дополнительно преобразует поля в html-безопасный вид. Добавляет поля с тильдой (без преобразования к безопасному виду) и преобразует url шаблоны в реальные ссылки, подставляя в них данные.
  • Принимает два параметра: boolean для включения/выключения преобразования полей в html-безопасный вид и boolean для включения/выключения полей с тильдой.
  • Чаще всего нужно использовать этот метод.

Функция GetNextElement()

  • Делает то же, что и GetNext(), только возвращает объект, а не массив, для большей гибкости.
  • Принимает те же параметры, что и GetNext().
  • Применять только в тех случаях, когда нужен именно объект _CIBElement, и больше никогда.

Примеры применения

Чтобы правильно применять эти методы чаще всего нужно использовать цикл while. До тех пор, пока выбранный метод не вернет false.

Пример с методом GetNext():

$items = [];
$dbItems = CIBlockElement::GetList(... Тут параметры ...);

while ($item = $dbItem->GetNext()) {
// как-то обрабатываем массив $item
...

// формируем итоговый список элементов
$items[] = $item;
}

Для двух других функций код останется таким же, изменится лишь строка с циклом.

Для Fetch()

while ($item = $dbItem->Fetch())

и для GetNextElement()

while ($item = $dbItem->GetNextElement()) {
$element = $item->GetFields();
$element['PROPERTIES'] = $item->GetProperties();

// как-то обрабатываем массив $element
...

// формируем итоговый список элементов
$items[] = $element;
}

Комментарии

Никто не оставлял свои комментарии