WordPress 核心自带了一些 REST 接口,可以处理文章,用户,评论等等这些资源。有时候我们需要自己加工一些接口功能,WordPress 支持我们添加这样的自定义 REST 接口。注册的接口相关的信息可以挂载到 rest_api_init 这个钩子函数上。注意接口用的是 register_rest_route 函数。
Endpoints
一个例子:
<?php function ninghao_rest_hello_callback() { return 'hello ~'; } function ninghao_rest_register_route() { register_rest_route( 'ninghao/v1', 'hello', [ 'methods' => 'GET', 'callback' => 'ninghao_rest_hello_callback' ] ); } add_action( 'rest_api_init', 'ninghao_rest_register_route');
为接口准备一个函数,函数里面添加接口需要的功能,比如去为准备点要返回的信息, 上面的 ninghao_rest_hello_callback 这个函数可以返回一个简单的 “hello ~”。在 ninghao_rest_register_route 函数里,使用 register_rest_route 注册了一个新的接口,地址是 “ninghao/v1/hello”,methods 方法是 GET,callback 指定使用 ninghao_rest_hello_callback 这个函数来处理对接口的请求。
在接口的地址里的 “ninghao/v1” 像是一个命名空间,或者叫前缀,这是为了跟别人添加的接口区分开。“hello ” 是接口地址的路由部分。
打开一个 REST 客户端,访问一下新添加的接口地址,会给我们返回一个简单的 “hello ~”。
请求
在接口的回调函数里,添加一个参数叫 $request,它里面会包含从客户端那里发送过来的一些信息。像这样:
function ninghao_rest_hello_callback( $request ) { $id = $request['id']; return 'hello ~ ' . $id; }
再添加一条新的路由:
register_rest_route( 'ninghao/v1', 'hello/(?P<id>[\d]+)', [ 'methods' => 'GET', 'callback' => 'ninghao_rest_hello_callback' ] );
路由同样使用 GET 方法,跟之前不同的是,这条路由支持一个 id 参数 (?P<id>[\d]+),参数的值必须是整数。这样请求这个接口地址的时候,可以为地址的 id 参数设置一个数字值,在接口的处理方法里我们可以得到请求里包含的数据,比如地址里的 id 参数的值。
得到请求里的数据
使用数组的形式:
$request['some_param'];
用帮手方法:
$request->get_param( 'some_param' );
得到合并到一块儿的参数值:
$request->get_params();
还可以得到不同部分的参数值:像这样:
$request->get_url_params(); $request->get_query_params(); $request->get_body_params(); $request->get_json_params(); $request->get_default_params();
文件:
$request->get_file_params();
消毒与验证
从用户那里发过来的数据,我们可以消消毒,还可以做一下验证。
register_rest_route( 'ninghao/v1', 'hello/(?P<id>[\d]+)', [ 'methods' => 'GET', 'callback' => 'ninghao_rest_hello_callback', 'args' => [ 'validate_callback' => 'ninghao_rest_hello_validate_id', 'sanitize_callback' => 'ninghao_rest_hello_check_id' ] ] );
验证:
function ninghao_rest_hello_validate_id( $param, $request, $key ) { return is_numeric( $param ); }
消毒:
function check_username( $value, $request, $param ) { // 做些消毒工作,然后返回消毒之后的值 return $value; }
示例:
下面是 WordPress 核心的 class-wp-rest-users-controller.php 里面的用户名使用的消毒方法。
public function check_username( $value, $request, $param ) { $username = (string) $value; if ( ! validate_username( $username ) ) { return new WP_Error( 'rest_user_invalid_username', __( 'Username contains invalid characters.' ), array( 'status' => 400 ) ); } /** This filter is documented in wp-includes/user.php */ $illegal_logins = (array) apply_filters( 'illegal_user_logins', array() ); if ( in_array( strtolower( $username ), array_map( 'strtolower', $illegal_logins ) ) ) { return new WP_Error( 'rest_user_invalid_username', __( 'Sorry, that username is not allowed.' ), array( 'status' => 400 ) ); } return $username; }
检查权限
在使用接口的时候,可以检查用户的权限。注册接口的时候添加一个权限检查的回调(permission_callback),在方法里用 WordPress 的 current_user_can 去检查对应的权限。
register_rest_route( 'ninghao/v1', 'hello/(?P<id>[\d]+)', [ 'methods' => 'GET', 'callback' => 'ninghao_rest_hello_callback', 'args' => [ 'validate_callback' => 'ninghao_rest_hello_validate_id' ], 'permission_callback' => 'ninghao_rest_hello_permission_check' ] );
权限检查回调:
function ninghao_rest_hello_permission_check() { return current_user_can( 'edit_others_posts' ); }
返回的值
接口的回调函数里面返回的东西会自动被转换成 JSON 格式的数据。改造一下之前的回调:
function ninghao_rest_hello_callback( $request ) { $user = get_userdata( $request['id'] ); return 'hello ~ ' . $user->data->display_name; }
在回调里,使用 WordPress 的 get_userdata 方法查询出指定 id 号的用户相关的数据,这个 id 号是从请求那里带过来的,然后我们在返回的数据里,添加了一个查询出来的指定用户的显示名($user->data->display_name)。
错误信息
在返回的数据里面,可以包含错误信息,我们可以返回一个 WP_Error 实例。
function ninghao_rest_hello_callback( $request ) { $user = get_userdata( $request['id'] ); if ( !$user ) { return new WP_Error( 'can_not_find_user', 'Invalid user', array( 'status' => 404 ) ); } return 'hello ~ ' . $user; }
现在,请求一个网站上不存在的用户,就会返回这个错误信息,注意 code 与 message 的值:
WordPress