大家好,今天咱们来聊聊 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 的其他骚操作!