各位观众老爷,晚上好! 今天咱们来聊聊 WordPress 里一个相当实用,但又经常被忽略的小家伙:get_term_by()
函数。 别看它名字平平无奇,功能却相当强大,能让你根据各种不同的字段来精准地找到你想要的分类术语(Term)。 就像个百变金刚,能根据你的指令变换搜索方式。
咱们今天就来把它扒个精光,从源码到用法,保证让你彻底掌握!
一、初识 get_term_by()
:分类术语的万能钥匙
首先,简单介绍一下 get_term_by()
函数的作用:
- 功能: 根据指定字段的值,从指定的分类法(taxonomy)中获取一个分类术语对象。
- 参数:
$field
(string) (Required): 要搜索的字段名,比如id
,slug
,name
等等。$value
(mixed) (Required): 要搜索的字段值。$taxonomy
(string) (Optional): 分类法的名称,比如category
,post_tag
。 默认为category
。$output
(string) (Optional): 输出格式。 默认为OBJECT
。 可以是OBJECT
,ARRAY_A
,ARRAY_N
。
- 返回值:
- 成功时,返回一个分类术语对象 (
WP_Term
对象) 或者数组,取决于$output
参数。 - 失败时,返回
false
。
- 成功时,返回一个分类术语对象 (
简单来说,你想找一个分类,但你只知道它的名字,或者 slug,或者 ID,就可以用 get_term_by()
函数来帮你搞定。 它就像一个数据库查询工具,只不过专门为 WordPress 的分类术语量身定制。
二、直击源码:get_term_by()
的内部运作
咱们直接深入到 WordPress 源码中,看看 get_term_by()
函数到底是怎么工作的。 这个函数位于 /wp-includes/taxonomy.php
文件中。
function get_term_by( $field, $value, $taxonomy = 'category', $output = OBJECT, $filter = 'raw' ) {
global $wpdb;
$taxonomy = sanitize_key( $taxonomy );
if ( empty( $taxonomy ) ) {
return false;
}
$tax = get_taxonomy( $taxonomy );
if ( ! $tax ) {
return false;
}
if ( ! is_scalar( $value ) ) {
return false;
}
if ( 'id' === $field ) {
$value = (int) $value;
if ( $value < 1 ) {
return false;
}
$term = get_term( $value, $taxonomy, $output, $filter );
if ( is_wp_error( $term ) ) {
return false;
}
return $term;
}
if ( 'slug' === $field ) {
$slug = sanitize_title( $value );
$term = get_term_by( 'name', $value, $taxonomy, $output, $filter );
if ($term && $term->slug === $slug) {
return $term;
}
$term = get_terms(
array(
'taxonomy' => $taxonomy,
'slug' => $slug,
'get' => 'all',
)
);
if ( is_wp_error( $term ) || empty( $term ) ) {
return false;
}
if ( is_array( $term ) ) {
$term = array_shift( $term );
}
return get_term( $term, $taxonomy, $output, $filter );
}
$id = $wpdb->get_var( $wpdb->prepare( "SELECT term_id FROM $wpdb->terms WHERE $field = %s", $value ) );
if ( ! $id ) {
return false;
}
return get_term( $id, $taxonomy, $output, $filter );
}
咱们来一行行地解读这段代码:
-
global $wpdb;
: 引入全局的 WordPress 数据库对象$wpdb
。 咱们要查数据库,肯定离不开它。 -
$taxonomy = sanitize_key( $taxonomy );
: 对分类法名称进行安全处理,防止恶意代码注入。 -
if ( empty( $taxonomy ) ) { return false; }
: 如果分类法名称为空,直接返回false
。 没有指定分类法,查个寂寞啊! -
$tax = get_taxonomy( $taxonomy ); if ( ! $tax ) { return false; }
: 检查指定的分类法是否存在。 如果不存在,也返回false
。 你要查的分类法都不存在,还查啥? -
if ( ! is_scalar( $value ) ) { return false; }
: 检查要搜索的值是否为标量类型(例如,字符串、整数、浮点数、布尔值)。 如果不是标量类型,也返回false
。 不支持数组和对象作为搜索值。 -
if ( 'id' === $field ) { ... }
: 如果搜索字段是id
:- 将
$value
转换为整数。 - 如果
$value
小于 1,返回false
。 ID 必须是正整数。 - 直接调用
get_term()
函数,通过 ID 获取分类术语对象。 这是最高效的方式,因为 WordPress 内部就是用 ID 来索引分类术语的。
- 将
-
if ( 'slug' === $field ) { ... }
: 如果搜索字段是slug
:- 首先对
$value
进行slug验证和转义。 - 尝试通过
name
字段来查找,如果找到了,并且slug
匹配,则直接返回。 - 如果没找到,就使用
get_terms()
函数,通过 slug 精确查找。 - 如果找到了多个结果,就返回第一个。
- 首先对
-
$id = $wpdb->get_var( $wpdb->prepare( "SELECT term_id FROM $wpdb->terms WHERE $field = %s", $value ) );
: 如果搜索字段不是id
或slug
,就执行一个 SQL 查询,从$wpdb->terms
表中查找符合条件的term_id
。$wpdb->prepare()
函数用于防止 SQL 注入。 -
if ( ! $id ) { return false; }
: 如果查询结果为空,说明没有找到符合条件的分类术语,返回false
。 -
return get_term( $id, $taxonomy, $output, $filter );
: 如果找到了term_id
,就调用get_term()
函数,通过 ID 获取分类术语对象并返回。
总结一下:
get_term_by()
函数首先会进行一系列的参数检查和安全处理。- 如果搜索字段是
id
,就直接调用get_term()
函数,这是最快的。 - 如果搜索字段是
slug
,先尝试通过name
查找,如果找不到,再调用get_terms()
函数通过 slug 精确查找。 - 如果搜索字段是其他字段,就执行一个 SQL 查询,从数据库中查找
term_id
,然后调用get_term()
函数获取分类术语对象。
三、实战演练:get_term_by()
的各种用法
光说不练假把式,咱们来看一些实际的例子,演示 get_term_by()
函数的各种用法。
1. 通过 ID 获取分类术语:
$term_id = 123; // 假设你要查找的分类术语的 ID 是 123
$term = get_term_by( 'id', $term_id, 'category' );
if ( $term ) {
echo '分类名称: ' . $term->name . '<br>';
echo '分类 Slug: ' . $term->slug . '<br>';
echo '分类 ID: ' . $term->term_id . '<br>';
} else {
echo '未找到 ID 为 ' . $term_id . ' 的分类术语。';
}
这段代码会根据 ID 123
查找 category
分类法下的分类术语,如果找到了,就输出分类的名称、slug 和 ID。
2. 通过 Slug 获取分类术语:
$term_slug = 'my-awesome-category'; // 假设你要查找的分类术语的 Slug 是 my-awesome-category
$term = get_term_by( 'slug', $term_slug, 'category' );
if ( $term ) {
echo '分类名称: ' . $term->name . '<br>';
echo '分类 Slug: ' . $term->slug . '<br>';
echo '分类 ID: ' . $term->term_id . '<br>';
} else {
echo '未找到 Slug 为 ' . $term_slug . ' 的分类术语。';
}
这段代码会根据 Slug my-awesome-category
查找 category
分类法下的分类术语,如果找到了,就输出分类的名称、slug 和 ID。
3. 通过名称获取分类术语:
$term_name = 'My Awesome Category'; // 假设你要查找的分类术语的名称是 My Awesome Category
$term = get_term_by( 'name', $term_name, 'category' );
if ( $term ) {
echo '分类名称: ' . $term->name . '<br>';
echo '分类 Slug: ' . $term->slug . '<br>';
echo '分类 ID: ' . $term->term_id . '<br>';
} else {
echo '未找到名称为 ' . $term_name . ' 的分类术语。';
}
这段代码会根据名称 My Awesome Category
查找 category
分类法下的分类术语,如果找到了,就输出分类的名称、slug 和 ID。
4. 获取自定义分类法下的分类术语:
$term_slug = 'my-custom-term'; // 假设你要查找的分类术语的 Slug 是 my-custom-term
$term = get_term_by( 'slug', $term_slug, 'my_custom_taxonomy' ); // my_custom_taxonomy 是你自定义的分类法名称
if ( $term ) {
echo '分类名称: ' . $term->name . '<br>';
echo '分类 Slug: ' . $term->slug . '<br>';
echo '分类 ID: ' . $term->term_id . '<br>';
} else {
echo '未找到 Slug 为 ' . $term_slug . ' 的分类术语。';
}
这段代码和前面的例子类似,只不过指定了分类法为 my_custom_taxonomy
,这是你自定义的分类法名称。
5. 以数组形式获取分类术语信息:
$term_id = 123; // 假设你要查找的分类术语的 ID 是 123
$term = get_term_by( 'id', $term_id, 'category', ARRAY_A ); // 指定输出格式为数组
if ( $term ) {
echo '分类名称: ' . $term['name'] . '<br>';
echo '分类 Slug: ' . $term['slug'] . '<br>';
echo '分类 ID: ' . $term['term_id'] . '<br>';
} else {
echo '未找到 ID 为 ' . $term_id . ' 的分类术语。';
}
这段代码和第一个例子类似,只不过指定了输出格式为 ARRAY_A
,这意味着 get_term_by()
函数会返回一个关联数组,而不是一个 WP_Term
对象。 你可以通过数组的键来访问分类术语的信息。
6. 安全使用 get_term_by()
由于 get_term_by()
最终可能会执行 SQL 查询,所以在使用时务必注意安全性,防止 SQL 注入。
- 参数验证: 确保传入的
$value
参数是经过验证和转义的。 可以使用sanitize_text_field()
或esc_sql()
函数进行处理。 - 避免直接使用用户输入: 尽量避免直接将用户输入作为
$value
参数传递给get_term_by()
函数。 如果必须使用用户输入,一定要进行严格的验证和过滤。
四、get_term_by()
与 get_term()
和 get_terms()
的区别
很多小伙伴可能对这三个函数感到困惑,咱们来简单对比一下:
函数名 | 功能 | 参数 | 返回值 | ||
---|---|---|---|---|---|
get_term_by() |
根据指定字段的值,从指定的分类法中获取一个分类术语对象。 相当于一个过滤器,让你根据特定条件来查找分类术语。 | 1. $field (string): 要搜索的字段名,比如 id , slug , name 等等。 2. $value (mixed): 要搜索的字段值。 3. $taxonomy (string) (Optional): 分类法的名称。 默认为 category 。 4. $output (string) (Optional): 输出格式。 默认为 OBJECT 。 可以是 OBJECT , ARRAY_A , ARRAY_N 。 |
成功时,返回一个分类术语对象 (WP_Term 对象) 或者数组,取决于 $output 参数。 失败时,返回 false 。 |
||
get_term() |
根据 ID 获取一个分类术语对象。 相当于一个直接访问工具,直接通过 ID 来获取分类术语。 | 1. $term (int |
object | string): 分类术语的 ID、对象或 Slug。 2. $taxonomy (string) (Optional): 分类法的名称。 默认为空字符串。 3. $output (string) (Optional): 输出格式。 默认为 OBJECT 。 可以是 OBJECT , ARRAY_A , ARRAY_N 。 4. $filter (string) (Optional): 过滤器名称。 默认为 raw 。 |
成功时,返回一个分类术语对象 (WP_Term 对象) 或者数组,取决于 $output 参数。 失败时,返回 WP_Error 对象或者 false 。 |
get_terms() |
获取指定分类法下的所有分类术语,或者根据指定的参数进行筛选。 相当于一个列表工具,可以获取多个分类术语。 | $args (array |
string) (Optional): 参数数组或者参数字符串。 用于指定分类法名称、排序方式、筛选条件等等。 | 成功时,返回一个包含分类术语对象的数组。 失败时,返回 WP_Error 对象或者空数组。 |
总结:
- 如果你知道分类术语的 ID,使用
get_term()
函数是最快的。 - 如果你知道分类术语的其他字段值(比如 slug 或 name),使用
get_term_by()
函数。 - 如果你要获取多个分类术语,或者需要根据复杂的条件进行筛选,使用
get_terms()
函数。
五、性能优化:避免过度使用 get_term_by()
虽然 get_term_by()
函数很方便,但是如果过度使用,可能会影响网站的性能。 尤其是当你使用非 id
字段进行搜索时,get_term_by()
函数需要执行 SQL 查询,这会增加数据库的负担。
建议:
- 尽量使用 ID 进行搜索: 如果可以,尽量使用分类术语的 ID 来获取信息,因为这是最快的。
- 缓存结果: 如果需要多次使用同一个分类术语的信息,可以将结果缓存起来,避免重复查询数据库。 可以使用 WordPress 的 Transient API 来实现缓存。
- 减少 SQL 查询次数: 尽量避免在循环中调用
get_term_by()
函数。 可以先使用get_terms()
函数获取所有需要的分类术语,然后进行循环处理。
六、总结
今天咱们深入剖析了 WordPress 的 get_term_by()
函数,从源码到用法,再到性能优化,相信你已经对它有了全面的了解。 get_term_by()
函数就像一个分类术语的万能钥匙,能让你根据各种不同的字段来精准地找到你想要的分类。
记住,合理使用 get_term_by()
函数,能让你的 WordPress 开发更加高效。 但也要注意性能优化,避免过度使用,让你的网站飞起来!
今天的讲座就到这里,感谢各位的观看! 如果有什么问题,欢迎在评论区留言,咱们一起探讨!