- 07.06.15
- 09:52
- 2148
- 0
Эти функции похожи:
get_the_terms
возвращает информацию о термах заданной таксономии, привязанных к заданному посту;wp_get_object_terms
возвращает информацию о термах одной или нескольких таксономий, привязанных к одному или нескольким постам, а также имеет ряд дополнительных опций.
Кроме этого каждая из них обладает другими особенностями, о которых надо знать.
Функция wp_get_object_terms
более сложна в применении и является базовой: она формирует SQL-запрос, получает от БД данные и обрабатывает их в соответствии с аргументами. Свой результат она не кеширует, а обращение к БД производит при каждом вызове.
1 |
$terms = wp_get_object_terms($post_ids, $taxonomies, $args) |
Первые два аргумента — $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
.
12345function myprefix_get_object_terms ($terms, $object_id_array, $taxonomy_array, $args) {...return $terms;}add_filter('get_object_terms', 'myprefix_get_object_terms', 10, 4);Идентификаторы постов и имена таксономий всегда передаются фильтру в виде массивов, даже если соотв. аргументы вызова
wp_get_object_terms
были одинарными значениями.- фильтруемый массив
'wp_get_object_terms'
, получающий в аргументах:- фильтруемый массив
$terms
; - строку с идентификаторами постов, разделёнными запятыми
$object_ids
; - строку с именами таксономий, разделёнными замятыми и взятыми в апострофы
$taxonomies
; - массив аргументов
$args
.
12345function myprefix_wp_get_object_terms ($terms, $object_ids, $taxonomies, $args) {...return $terms;}add_filter('wp_get_object_terms', 'myprefix_wp_get_object_terms', 10, 4);Строки с идентификаторами постов и таксономиями фильтру передаются те же, что использовались функцией для построения SQL-запросов.
- фильтруемый массив
Фильтры выполняются друг за другом непосредственно перед завершением функции.
Отдавать предпочтение функции wp_get_object_terms
следует, если
- необходимо получить термы для нескольких постов и/или нескольких таксономий;
- необходимо получить только к.-л. один параметр термов (имена, ярлыки или идентификаторы);
- не ожидается многократных вызовов функции с одинаковыми аргументами (в ходе обработки одного http-запроса);
- кеширование результата предусмотрено вызывающей функцией;
- количество обращений к БД не имеет значения (напр., при работе в админской консоли, происходящей значительно реже простых посещений сайта).
Замечание: если выполняется запрос идентификаторов ('fields' => 'ids'
), после которого для каждого из них терм извлекается вызовом get_term
, то выгоднее будет запросить термы полностью ('fields' => 'all'
или не задан), а результат обработать вызовом wp_list_pluck($terms, 'term_id')
. В этом случае вызовы get_term
обращения к БД производить не будут.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// антипаттерн: так обращений к БД будет N+1, где N - количество термов у поста $post_id: $a_ids = wp_get_post_terms($post_id, 'taxonomy', array('fields' => 'ids')); foreach ($a_ids as $term_id) { $term = get_term($term_id, 'taxonomy'); // терм не кеширован - происходит обращение к БД ... } // а так обращение к БД будет одно: $a_ids = wp_list_pluck(wp_get_post_terms($post_id, 'taxonomy'), 'term_id'); foreach ($a_ids as $term_id) { $term = get_term($term_id, 'taxonomy'); // терм кеширован - обращений к БД не происходит ... } |
Функция get_the_terms
более проста в применении и работает только с одним постом и одной таксономией:
1 |
$terms = get_the_terms($post_id, $taxonomy); |
Первым аргументом может быть как идентификатор, так и объект поста.
Особенностью функции является кеширование её результата, поэтому при повторных вызовах с теми же аргументами обращений к БД не потребуется. Перед возвратом массив термов прогоняется через одноимённый фильтр 'get_the_terms'
, вторым и третьим аргументами которого являются идентификатор поста и имя таксономии:
1 2 3 4 5 |
function myprefix_get_the_terms ($terms, $post_id, $taxonomy) { ... return $terms; } add_filter('get_the_terms', 'myprefix_get_the_terms', 10, 3); |
Самостоятельно к БД функция get_the_terms
не обращается — для этого она вызывает wp_get_object_terms
, являясь, таким образом, функцией-обёрткой. Вызов происходит так:
1 |
$terms = wp_get_object_terms( $post->ID, $taxonomy ); |
Непустой результат соответствует варианту '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.
Замечание: на момент публикации данной заметки текущей версией WordPress была 4.2.2.