嘿,大家好,欢迎来到今天的“扒光 WordPress REST API”讲座。今天咱们要聊聊一个非常关键的函数:rest_get_all_endpoints()。这个函数就像是 WordPress REST API 的地图,它能告诉你所有的“宝藏”都藏在哪里。
准备好了吗?咱们这就开始寻宝!
第一站:rest_get_all_endpoints() 函数的真面目
首先,让我们看看 rest_get_all_endpoints() 函数究竟长什么样。这个函数定义在 wp-includes/rest-api.php 文件中,别害怕,咱们一步步来拆解它。
/**
* Gets all registered REST API endpoints.
*
* @since 4.4.0
*
* @global WP_REST_Server $wp_rest_server REST server instance.
*
* @return array Registered REST API endpoints, organized by route.
*/
function rest_get_all_endpoints() {
global $wp_rest_server;
if ( empty( $wp_rest_server ) ) {
return array();
}
return $wp_rest_server->get_routes();
}
是不是很简单? 实际上,它主要做了两件事:
- 获取全局
$wp_rest_server对象:global $wp_rest_server;这一行代码声明我们要使用全局的$wp_rest_server变量。这个变量是WP_REST_Server类的实例,负责管理所有的 REST API 路由。 - 调用
$wp_rest_server->get_routes():return $wp_rest_server->get_routes();这行代码才是关键。它调用了$wp_rest_server对象的get_routes()方法,这个方法会返回一个包含所有已注册 REST API 端点的数组。
所以,rest_get_all_endpoints() 本身只是一个“传话筒”,真正的核心逻辑在 WP_REST_Server 类的 get_routes() 方法中。
第二站:深入 WP_REST_Server::get_routes()
现在,我们得去 WP_REST_Server 类里一探究竟。这个类也定义在 wp-includes/rest-api.php 文件中。
/**
* Retrieves all registered routes.
*
* @since 4.4.0
*
* @return array Key-value array of registered routes.
*/
public function get_routes() {
return $this->endpoints;
}
哇哦,更简单了!get_routes() 方法直接返回了 $this->endpoints 这个属性。 $endpoints 是 WP_REST_Server 类的一个私有属性,它存储了所有注册的 REST API 路由。
所以,真正的秘密就藏在 $this->endpoints 里!
第三站:$endpoints 的结构:REST API 的藏宝图
$endpoints 属性是一个多维数组,它的结构是这样的:
[
'/route/path' => [
[
'methods' => [ 'GET', 'POST', ... ],
'callback' => 'function_name', // 或者 [ $object, 'method_name' ]
'args' => [ /* 参数定义 */ ],
'permission_callback' => 'function_name',
// ... 其他属性
],
[
// 针对同一个路由,可能有不同的方法和回调
],
],
'/another/route' => [
// ...
],
]
让我们用一个表格来更清晰地展示这个结构:
| 键 (Key) | 值 (Value) |
|---|---|
/route/path |
一个字符串,表示 REST API 的路由路径,例如 /wp/v2/posts。 |
[ ... ] |
一个数组,包含了针对该路由的所有注册信息。 每个元素都是一个数组,代表一个特定的方法 (GET, POST, 等) 和回调函数。 |
methods |
一个数组,包含了该路由支持的 HTTP 方法,例如 ['GET', 'POST']。 |
callback |
一个回调函数,当请求匹配到该路由和方法时,会执行这个函数。 可以是函数名 (字符串) 或者一个数组 [ $object, 'method_name' ],表示对象的方法。 |
args |
一个数组,定义了该路由的参数。 每个参数都有自己的属性,例如 type (参数类型), required (是否必须), validate_callback (验证回调函数), sanitize_callback (清理回调函数) 等。 |
permission_callback |
一个回调函数,用于检查用户是否有权限访问该路由。 如果该函数返回 true 或 WP_REST_Response 对象,则允许访问;否则,拒绝访问。 |
schema |
一个数组或回调函数,用于描述该路由的请求和响应的 JSON Schema。 这有助于客户端了解如何使用该 API 以及期望的响应格式。 从 WordPress 5.5 开始,推荐使用 schema 而不是 args 来定义参数。 |
| … | 还有其他一些属性,例如 accept_json (是否接受 JSON 请求), show_in_index (是否显示在 API 索引中) 等。 |
举个栗子:/wp/v2/posts 路由
让我们以 /wp/v2/posts 这个常见的路由为例,看看它的 $endpoints 数组可能长什么样:
[
'/wp/v2/posts' => [
[
'methods' => [ 'GET' ],
'callback' => 'WP_REST_Posts_Controller->get_items',
'permission_callback' => 'WP_REST_Posts_Controller->get_items_permissions_check',
'args' => [
'context' => [
'default' => 'view',
],
'page' => [
'type' => 'integer',
'default' => 1,
],
// ... 其他参数
],
'schema' => 'WP_REST_Posts_Controller->get_item_schema',
],
[
'methods' => [ 'POST' ],
'callback' => 'WP_REST_Posts_Controller->create_item',
'permission_callback' => 'WP_REST_Posts_Controller->create_item_permissions_check',
'args' => [
'title' => [
'type' => 'string',
'required' => true,
],
'content' => [
'type' => 'string',
],
// ... 其他参数
],
'schema' => 'WP_REST_Posts_Controller->get_item_schema',
],
],
]
在这个例子中,/wp/v2/posts 路由支持两种方法:GET (获取文章列表) 和 POST (创建新文章)。 每种方法都有自己的回调函数、权限检查函数和参数定义。
第四站:如何使用 rest_get_all_endpoints() 获取所有端点
现在,我们已经了解了 rest_get_all_endpoints() 函数的作用和 $endpoints 数组的结构,接下来看看如何实际使用它。
$all_endpoints = rest_get_all_endpoints();
// 遍历所有端点
foreach ( $all_endpoints as $route => $handlers ) {
echo "Route: " . esc_html( $route ) . "<br>";
// 遍历该路由的所有处理程序
foreach ( $handlers as $handler ) {
echo " Methods: " . implode( ', ', $handler['methods'] ) . "<br>";
echo " Callback: ";
if ( is_string( $handler['callback'] ) ) {
echo esc_html( $handler['callback'] ) . "<br>";
} elseif ( is_array( $handler['callback'] ) ) {
echo esc_html( get_class( $handler['callback'][0] ) . '->' . $handler['callback'][1] ) . "<br>";
} else {
echo "Unknown callback type<br>";
}
echo " Permission Callback: ";
if ( is_string( $handler['permission_callback'] ) ) {
echo esc_html( $handler['permission_callback'] ) . "<br>";
} elseif ( is_array( $handler['permission_callback'] ) ) {
echo esc_html( get_class( $handler['permission_callback'][0] ) . '->' . $handler['permission_callback'][1] ) . "<br>";
} else {
echo "Unknown permission callback type<br>";
}
echo " Arguments:<br>";
if ( ! empty( $handler['args'] ) ) {
echo "<pre>";
print_r( $handler['args'] );
echo "</pre>";
} else {
echo " None<br>";
}
}
echo "<br>";
}
这段代码会遍历所有的 REST API 端点,并打印出每个路由的路径、支持的方法、回调函数、权限检查函数和参数定义。 你可以将这段代码放在你的 WordPress 主题的 functions.php 文件中,或者创建一个自定义插件来运行它。 记得在运行后移除这段代码,因为它可能会暴露敏感信息。
第五站:为什么要获取所有端点?
你可能会问,为什么要费这么大劲获取所有的 REST API 端点呢? 其实有很多用途:
- 调试和学习: 通过查看所有端点,你可以更好地了解 WordPress REST API 的结构和功能,方便调试和学习。
- 自定义开发: 在自定义 REST API 客户端时,你可以使用这些信息来生成 API 文档、构建请求和处理响应。
- 安全审计: 你可以检查所有端点的权限设置,确保没有未授权的访问。
- 自动化测试: 你可以使用这些信息来编写自动化测试脚本,验证 API 的功能是否正常。
- 插件开发: 查找某个特定插件是否注册了 API 接口,以及这些接口的参数和权限。
第六站:rest_get_server():通往 $wp_rest_server 的另一扇门
除了直接使用全局 $wp_rest_server 变量,你还可以使用 rest_get_server() 函数来获取 WP_REST_Server 实例。
/**
* Gets the REST server instance.
*
* @since 4.4.0
*
* @return WP_REST_Server Server instance.
*/
function rest_get_server() {
global $wp_rest_server;
if ( empty( $wp_rest_server ) ) {
$wp_rest_server = new WP_REST_Server;
/**
* Fires after the REST API is initialized.
*
* @since 4.4.0
*
* @param WP_REST_Server $wp_rest_server REST server instance.
*/
do_action( 'rest_api_init', $wp_rest_server );
}
return $wp_rest_server;
}
rest_get_server() 函数会返回全局 $wp_rest_server 对象,如果 $wp_rest_server 对象还没有被创建,它会先创建一个新的 WP_REST_Server 实例,并触发 rest_api_init action。
所以,你可以这样使用 rest_get_server() 来获取所有端点:
$server = rest_get_server();
$all_endpoints = $server->get_routes();
// 接下来就可以像前面一样遍历 $all_endpoints 了
第七站:rest_api_init action:REST API 的启动仪式
rest_get_server() 函数中提到了 rest_api_init action。 这个 action 是在 REST API 初始化之后触发的,你可以在这个 action 中注册你自己的 REST API 路由。
add_action( 'rest_api_init', 'my_register_rest_route' );
function my_register_rest_route() {
register_rest_route( 'my-plugin/v1', '/my-endpoint', array(
'methods' => 'GET',
'callback' => 'my_endpoint_callback',
) );
}
function my_endpoint_callback( WP_REST_Request $request ) {
return array( 'message' => 'Hello from my endpoint!' );
}
这段代码会在 my-plugin/v1 命名空间下注册一个名为 /my-endpoint 的 REST API 路由。 当用户访问这个路由时,会执行 my_endpoint_callback 函数,并返回一个包含 "Hello from my endpoint!" 消息的 JSON 响应。
总结:REST API 的寻宝之旅
今天,我们一起深入探索了 WordPress REST API 的核心函数 rest_get_all_endpoints()。 我们了解了它的作用、WP_REST_Server 类的结构以及 $endpoints 数组的格式。 我们还学习了如何使用 rest_get_all_endpoints() 和 rest_get_server() 函数来获取所有注册的 REST API 端点,以及如何使用 rest_api_init action 来注册你自己的 REST API 路由。
希望这次寻宝之旅让你对 WordPress REST API 有了更深入的了解。 记住,REST API 是 WordPress 的强大武器,掌握它,你就能创造出更强大的 WordPress 应用!
下次再见!