Разница между get_the_terms и wp_get_object_terms

  • 07.06.15
  • 09:52
  • 1987
  • 0

Эти функции похожи:

  • get_the_terms возвращает информацию о термах заданной таксономии, привязанных к заданному посту;
  • wp_get_object_terms возвращает информацию о термах одной или нескольких таксономий, привязанных к одному или нескольким постам, а также имеет ряд дополнительных опций.

Кроме этого каждая из них обладает другими особенностями, о которых надо знать.

Функция wp_get_object_terms более сложна в применении и является базовой: она формирует SQL-запрос, получает от БД данные и обрабатывает их в соответствии с аргументами. Свой результат она не кеширует, а обращение к БД производит при каждом вызове.

Первые два аргумента — $post_ids и $taxonomies — могут быть как значениями, так и массивами значений. Третий аргумент — $args — опциональный массив дополнительных параметров, позволяющих

  • определять поле и порядок сортировки (параметры orderby и order);
  • задавать вид возвращаемых значений (параметр fields);
  • фильтровать термы по терму-родителю (параметр parent; для иерархичных таксономий).

За точным определением аргументов рекомендуется обратиться к кодексу (см. wp_get_object_terms на кодексе) и к исходникам (см. wp-includes/taxonomy.php).

Замечание следует сделать только о значениях 'all' и 'all_with_object_id' параметра 'field', т. к. на момент публикации данной заметки их описания на кодексе были одинаковыми: «all matching term’s objects will be returned» — «будут возвращены объекты всех подходящих термов».

В обоих случаях функция возвращает массив объектов с информацией о термах — их структура описана в заметке Параметры терма в WordPress.

По умолчанию полю 'fields' присваивается значение 'all'.

Различия между 'all' и 'all_with_object_id' проявляются при запросе термов для множества постов:

  • если 'fields' имеет значение 'all_with_object_id', в результат включаются все термы каждого из заданных постов: в описывающих термы структурах имеется поле object_id с идентификатором обладающего термом поста;
  • если установлен 'all' (или если 'fields' не задан явно), результирующий массив содержит структуры термов, каждый из которых прикреплен хотя бы к одному из заданных постов; поле object_id у структур отсутствует, повторов термов в массиве нет.

Значение 'all_with_object_id' полезно, когда требуется получить информацию по каждому посту в наборе. Вся информация извлекается из БД одним запросом, поэтому один такой вызов выгоднее нескольких, сделанных для каждого поста и/или каждой таксономии в отдельности. Точно также один вызов с 'all*' обойдётся дешевле нескольких с одиночными полями (names, slugs, ids).

При обоих вариантах 'all*' происходит кеширование полученных термов (но не результата функции). Поэтому

  • при получении тех же термов вызовом get_term обращения к БД не потребуется;
  • после вызова с all_with_object_id терм кешируется с полем object_id — при получении такого терма от get_term это поле следует игнорировать;
  • кешированностью термов wp_get_object_terms никак не руководствуется и выполняет запрос к БД при каждом вызове.

Возвращаемое значение всегда является либо массивом, либо объектом класса WP_Error, если к.-л. из заданных таксономий не была зарегистрирована. Если подходящие термы не найдены, итоговый массив будет пуст. Такое может произойти в случае, когда посты с указанными идентификаторами отсутствуют или не имеют термов заданных таксономий, а также когда родитель ни одного из прикреплённых термов не соответствует указанному в аргументе 'parent'.

Перед возвратом массива функция фильтрует его по двум хукам:

  • 'get_object_terms', получающий в аргументах:
    • фильтруемый массив $terms,
    • массив идентификаторов постов $object_id_array,
    • массив таксономий $taxonomy_array,
    • массив аргументов $args.

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

  • 'wp_get_object_terms', получающий в аргументах:
    • фильтруемый массив $terms;
    • строку с идентификаторами постов, разделёнными запятыми $object_ids;
    • строку с именами таксономий, разделёнными замятыми и взятыми в апострофы $taxonomies;
    • массив аргументов $args.

    Строки с идентификаторами постов и таксономиями фильтру передаются те же, что использовались функцией для построения SQL-запросов.

Фильтры выполняются друг за другом непосредственно перед завершением функции.

Отдавать предпочтение функции wp_get_object_terms следует, если

  • необходимо получить термы для нескольких постов и/или нескольких таксономий;
  • необходимо получить только к.-л. один параметр термов (имена, ярлыки или идентификаторы);
  • не ожидается многократных вызовов функции с одинаковыми аргументами (в ходе обработки одного http-запроса);
  • кеширование результата предусмотрено вызывающей функцией;
  • количество обращений к БД не имеет значения (напр., при работе в админской консоли, происходящей значительно реже простых посещений сайта).

Замечание: если выполняется запрос идентификаторов ('fields' => 'ids'), после которого для каждого из них терм извлекается вызовом get_term, то выгоднее будет запросить термы полностью ('fields' => 'all' или не задан), а результат обработать вызовом wp_list_pluck($terms, 'term_id'). В этом случае вызовы get_term обращения к БД производить не будут.

Функция get_the_terms более проста в применении и работает только с одним постом и одной таксономией:

Первым аргументом может быть как идентификатор, так и объект поста.

Особенностью функции является кеширование её результата, поэтому при повторных вызовах с теми же аргументами обращений к БД не потребуется. Перед возвратом массив термов прогоняется через одноимённый фильтр 'get_the_terms', вторым и третьим аргументами которого являются идентификатор поста и имя таксономии:

Самостоятельно к БД функция get_the_terms не обращается — для этого она вызывает wp_get_object_terms, являясь, таким образом, функцией-обёрткой. Вызов происходит так:

Непустой результат соответствует варианту 'fields' => 'all' — массив объектов термов, либо экземпляр класса WP_Error, когда таксономия неизвестна. Если подходящих термов пост не имеет, вместо пустого массива функция get_the_terms вернёт false.

P.S.: есть ещё одна похожая функция — wp_get_post_terms. Она также является обёрткой над wp_get_object_terms, но отличается от неё лишь тем, что принимает единственный идентификатор поста. В остальном она полностью идентична wp_get_object_terms.

Резюме
  • функция wp_get_object_terms является базовой, функция get_the_terms её использует;
  • функция wp_get_object_terms не кеширует свой результат, функция get_the_terms — кеширует;
  • обе функции фильтруют результат перед его возвратом:
    • wp_get_object_terms — по хукам 'get_object_terms' и 'wp_get_object_terms';
    • get_the_terms — по хуку 'get_the_terms';
  • если посты подходящих термов не имеют, wp_get_object_terms возвращает пустой массив, а get_the_terms — значение false;
  • функция wp_get_object_terms предпочтительна
    • при одновременной работе со множеством постов и/или таксономий;
    • при отсутствии нужды в кешировании или при самостоятельной его реализации;
    • при работе только с идентификаторами, только с ярлыками или только с именами термов;
    • при необходимости сортировать результат по к.-л. полю в определённом направлении;
    • при необходимости фильтрации по родительскому терму (для иерархических таксономий);
    • когда количество обращений к БД не имеет значения (при отображении или применении к.-л. настроек, например);
  • функция get_the_terms предпочтительна при
    • работе с одним постом и одной таксономией;
    • высокой вероятности повторных вызовов с теми же аргументами.
Полезные ссылки

Замечание: на момент публикации данной заметки текущей версией WordPress была 4.2.2.

Оставить комментарий

Добавить комментарий