大家好,今天咱们来聊聊 WordPress REST API 的“私人订制”:register_rest_field()
函数源码剖析
嗨,各位!今天咱们不开玩笑,直接上干货。咱们来扒一扒 WordPress REST API 里的一个关键函数—— register_rest_field()
。它就像个魔法棒,能让你在 API 响应里添加自己想要的字段,想加啥加啥,简直不要太爽!
一、REST API 的“缺憾”与 register_rest_field()
的登场
话说 WordPress REST API 提供了各种各样的数据接口,方便我们获取文章、页面、用户等等信息。但是,有时候自带的字段可能不够用,比如:
- 你想在文章里加个“阅读次数”字段。
- 你想在用户里加个“个人简介”字段(假设这个简介不是标准的用户元数据)。
- 你想根据某些条件计算出一个新的字段值。
这时候,光靠 WordPress 默认的 API 就没辙了,得自己动手丰衣足食。register_rest_field()
就是为此而生的,它允许我们注册自定义的 REST 字段,让 API 响应带上我们想要的额外信息。
二、register_rest_field()
的基本用法:手把手教你“私人订制”
register_rest_field()
函数的原型是这样的:
register_rest_field(
string $object_type,
string $attribute,
array $args
);
$object_type
:指定你要往哪个对象类型里添加字段,比如'post'
(文章)、'page'
(页面)、'user'
(用户)等等。$attribute
:指定你自定义字段的名称,这个名称会出现在 API 响应里。$args
:一个数组,包含字段的获取、更新、权限控制等信息。
咱们先来个简单的例子,往文章里加个“阅读次数”字段,让 API 响应里显示每篇文章的阅读次数。
function my_register_rest_fields() {
register_rest_field(
'post', // 对象类型:文章
'reading_count', // 字段名称:阅读次数
array(
'get_callback' => 'my_get_post_reading_count', // 获取字段值的回调函数
'update_callback' => null, // 更新字段值的回调函数,如果不需要更新,设为 null
'schema' => null, // 字段的 Schema,用于描述字段的数据类型和格式
)
);
}
add_action( 'rest_api_init', 'my_register_rest_fields' );
function my_get_post_reading_count( $object, $field_name, $request ) {
// 获取文章的阅读次数(假设你已经有了一个获取阅读次数的函数)
$reading_count = get_post_meta( $object['id'], 'reading_count', true );
return intval( $reading_count ); // 确保返回的是整数
}
这段代码做了什么?
my_register_rest_fields()
函数:- 调用
register_rest_field()
注册一个自定义字段。 'post'
:指定了文章对象。'reading_count'
:指定了字段名称为reading_count
。'get_callback'
:指定了获取字段值的回调函数为my_get_post_reading_count()
。'update_callback'
:设置为null
,表示这个字段不能通过 API 更新。'schema'
:设置为null
,表示没有定义 Schema。
- 调用
my_get_post_reading_count()
函数:- 接收三个参数:
$object
(当前对象,比如文章)、$field_name
(字段名称)、$request
(请求对象)。 - 通过
$object['id']
获取文章 ID。 - 调用
get_post_meta()
获取文章的reading_count
元数据值。 - 将值转换为整数并返回。
- 接收三个参数:
add_action( 'rest_api_init', 'my_register_rest_fields' )
:- 在
rest_api_init
钩子上注册my_register_rest_fields()
函数,确保在 REST API 初始化时注册自定义字段。
- 在
现在,当你访问文章的 REST API 接口时(比如 /wp-json/wp/v2/posts/123
),响应里就会多出一个 reading_count
字段,显示文章的阅读次数。
三、$args
数组详解:控制字段的方方面面
$args
数组是 register_rest_field()
函数的核心,它决定了字段的各种行为。咱们来详细看看 args
数组里可以包含哪些参数:
参数名 | 类型 | 描述 |
---|---|---|
get_callback |
callable | 必须。用于获取字段值的回调函数。接收三个参数:$object (当前对象)、$field_name (字段名称)、$request (请求对象)。必须返回字段的值。 |
update_callback |
callable | 用于更新字段值的回调函数。接收三个参数:$value (要更新的值)、$object (当前对象)、$field_name (字段名称)。如果不需要更新,可以设为 null 。 |
schema |
array | 用于描述字段的 Schema,包括字段的数据类型、格式、描述等信息。Schema 可以让 API 客户端更好地了解字段的含义和用法。 |
permission_callback |
callable | 用于控制字段的访问权限的回调函数。接收一个参数:$request (请求对象)。必须返回 true (允许访问)或 false (禁止访问)。如果没有指定,默认情况下所有用户都可以访问该字段。 |
sanitize_callback |
callable | 用于对要更新的值进行清理和验证的回调函数。接收一个参数:$value (要更新的值)。必须返回清理后的值。 |
1. get_callback
:获取字段值
这个回调函数是必须要指定的,它决定了字段的值怎么来的。 咱们刚才的例子里已经用过了。再来个例子,获取文章的作者姓名:
function my_get_post_author_name( $object, $field_name, $request ) {
$author_id = $object['author'];
$author = get_user_by( 'id', $author_id );
return $author->display_name;
}
register_rest_field(
'post',
'author_name',
array(
'get_callback' => 'my_get_post_author_name',
'update_callback' => null,
'schema' => null,
)
);
2. update_callback
:更新字段值
如果你希望可以通过 API 更新这个字段的值,就需要指定 update_callback
。 比如,允许通过 API 修改文章的阅读次数:
function my_update_post_reading_count( $value, $object, $field_name ) {
// 验证 $value 是否为整数
if ( ! is_numeric( $value ) ) {
return new WP_Error( 'invalid_reading_count', '阅读次数必须是数字', array( 'status' => 400 ) );
}
// 更新文章的阅读次数
update_post_meta( $object->ID, 'reading_count', intval( $value ) );
return true; // 必须返回 true,表示更新成功
}
register_rest_field(
'post',
'reading_count',
array(
'get_callback' => 'my_get_post_reading_count',
'update_callback' => 'my_update_post_reading_count',
'schema' => array(
'type' => 'integer',
'description' => '文章的阅读次数',
'context' => array( 'view', 'edit' ), // 表示在 view 和 edit 上下文中都显示
'arg_options' => array(
'sanitize_callback' => 'absint', // 对输入的值进行清理,确保是正整数
),
),
)
);
注意:
update_callback
的返回值必须是true
(表示更新成功)或者一个WP_Error
对象(表示更新失败)。- 在
schema
里定义了arg_options
,指定了sanitize_callback
,用于对输入的值进行清理,确保是正整数。
3. schema
:描述字段的数据类型和格式
schema
用于描述字段的数据类型、格式、描述等信息,可以让 API 客户端更好地了解字段的含义和用法。
schema
数组可以包含以下参数:
参数名 | 类型 | 描述 |
---|---|---|
type |
string | 字段的数据类型,比如 'string' 、'integer' 、'boolean' 、'array' 、'object' 。 |
description |
string | 字段的描述信息。 |
enum |
array | 字段的可选值列表。 |
format |
string | 字段的格式,比如 'date' 、'date-time' 、'email' 、'url' 。 |
context |
array | 字段在哪些上下文中显示,比如 ['view', 'edit'] 表示在查看和编辑上下文中都显示。 |
readonly |
boolean | 是否只读,如果是 true ,则不能通过 API 更新该字段。 |
arg_options |
array | 用于定义字段的参数选项,比如 sanitize_callback (清理回调函数)、validate_callback (验证回调函数)。 |
properties |
array | 如果字段是一个对象,可以用 properties 定义对象的属性。 |
items |
array | 如果字段是一个数组,可以用 items 定义数组的元素类型。 |
例如,定义一个包含作者姓名和邮箱的对象:
register_rest_field(
'post',
'author_info',
array(
'get_callback' => 'my_get_post_author_info',
'update_callback' => null,
'schema' => array(
'type' => 'object',
'description' => '文章作者的信息',
'properties' => array(
'name' => array(
'type' => 'string',
'description' => '作者姓名',
),
'email' => array(
'type' => 'string',
'description' => '作者邮箱',
'format' => 'email',
),
),
),
)
);
function my_get_post_author_info( $object, $field_name, $request ) {
$author_id = $object['author'];
$author = get_user_by( 'id', $author_id );
return array(
'name' => $author->display_name,
'email' => $author->user_email,
);
}
4. permission_callback
:控制字段的访问权限
permission_callback
用于控制字段的访问权限,只有通过权限验证的用户才能访问该字段。
例如,只有管理员才能查看文章的阅读次数:
function my_check_reading_count_permission( $request ) {
return current_user_can( 'manage_options' ); // 只有管理员才能查看
}
register_rest_field(
'post',
'reading_count',
array(
'get_callback' => 'my_get_post_reading_count',
'update_callback' => null,
'schema' => null,
'permission_callback' => 'my_check_reading_count_permission',
)
);
5. sanitize_callback
:清理和验证要更新的值
sanitize_callback
用于对要更新的值进行清理和验证,确保数据的安全性和准确性。
例如,确保阅读次数是正整数:
function my_sanitize_reading_count( $value ) {
return absint( $value ); // 将值转换为正整数
}
register_rest_field(
'post',
'reading_count',
array(
'get_callback' => 'my_get_post_reading_count',
'update_callback' => 'my_update_post_reading_count',
'schema' => array(
'type' => 'integer',
'description' => '文章的阅读次数',
'context' => array( 'view', 'edit' ),
'arg_options' => array(
'sanitize_callback' => 'my_sanitize_reading_count',
),
),
)
);
四、register_rest_field()
源码浅析:看看幕后英雄
register_rest_field()
函数的源码并不复杂,主要就是把我们注册的字段信息保存起来,然后在 API 响应的时候调用 get_callback
获取字段值。
function register_rest_field( $object_type, $attribute, $args ) {
global $wp_rest_additional_fields;
if ( ! isset( $wp_rest_additional_fields ) || ! is_array( $wp_rest_additional_fields ) ) {
$wp_rest_additional_fields = array();
}
$object_types = (array) $object_type;
foreach ( $object_types as $type ) {
if ( ! isset( $wp_rest_additional_fields[ $type ] ) || ! is_array( $wp_rest_additional_fields[ $type ] ) ) {
$wp_rest_additional_fields[ $type ] = array();
}
$wp_rest_additional_fields[ $type ][ $attribute ] = $args;
}
return true;
}
这段代码做了什么?
- 获取全局变量
$wp_rest_additional_fields
,这是一个数组,用于存储注册的自定义字段信息。 - 将
$object_type
转换为数组,允许同时注册多个对象类型。 - 遍历
$object_types
数组,将字段信息存储到$wp_rest_additional_fields
数组中。
关键在于,WordPress 会在生成 REST API 响应的时候,遍历 $wp_rest_additional_fields
数组,调用对应的 get_callback
函数,获取字段值,然后添加到响应中。
五、总结:register_rest_field()
的强大之处
register_rest_field()
函数是 WordPress REST API 的一个强大工具,它可以让我们:
- 自定义 API 响应,添加我们需要的额外信息。
- 控制字段的访问权限,保护敏感数据。
- 清理和验证要更新的值,确保数据的安全性和准确性。
- 使用 Schema 描述字段的数据类型和格式,方便 API 客户端使用。
掌握了 register_rest_field()
函数,你就可以像定制西装一样,为 WordPress REST API “私人订制”各种各样的字段,满足你的各种需求。
好了,今天的讲座就到这里。希望大家都能灵活运用 register_rest_field()
函数,打造更加强大的 WordPress REST API! 下次有机会再跟大家聊聊 REST API 的其他骚操作!