函数文档

rest_filter_response_fields()

💡 云策文档标注

概述

rest_filter_response_fields() 是一个 WordPress REST API 过滤器函数,用于根据请求中的 _fields 参数,裁剪响应数据,仅返回允许的字段集。它处理嵌套字段,并支持数组数据。

关键要点

  • 函数作用:过滤 REST API 响应,只包含请求中指定的字段,提高数据传输效率。
  • 参数:接受 $response(WP_REST_Response)、$server(WP_REST_Server)和 $request(WP_REST_Request),返回裁剪后的 WP_REST_Response。
  • 处理逻辑:检查 _fields 参数和错误响应,解析字段列表,构建字段层次结构,并递归应用字段过滤。
  • 相关函数:依赖 _rest_array_intersect_key_recursive()、wp_parse_list() 和 wp_is_numeric_array() 等辅助函数。

代码示例

function rest_filter_response_fields( $response, $server, $request ) {
    if ( ! isset( $request['_fields'] ) || $response->is_error() ) {
        return $response;
    }

    $data = $response->get_data();

    $fields = wp_parse_list( $request['_fields'] );

    if ( 0 === count( $fields ) ) {
        return $response;
    }

    $fields = array_map( 'trim', $fields );

    $fields_as_keyed = array();
    foreach ( $fields as $field ) {
        $parts = explode( '.', $field );
        $ref   = &$fields_as_keyed;
        while ( count( $parts ) > 1 ) {
            $next = array_shift( $parts );
            if ( isset( $ref[ $next ] ) && true === $ref[ $next ] ) {
                break 2;
            }
            $ref[ $next ] = isset( $ref[ $next ] ) ? $ref[ $next ] : array();
            $ref          = &$ref[ $next ];
        }
        $last         = array_shift( $parts );
        $ref[ $last ] = true;
    }

    if ( wp_is_numeric_array( $data ) ) {
        $new_data = array();
        foreach ( $data as $item ) {
            $new_data[] = _rest_array_intersect_key_recursive( $item, $fields_as_keyed );
        }
    } else {
        $new_data = _rest_array_intersect_key_recursive( $data, $fields_as_keyed );
    }

    $response->set_data( $new_data );

    return $response;
}

注意事项

  • 该函数从 WordPress 4.8.0 版本开始引入,使用时需确保版本兼容性。
  • 如果 _fields 参数未设置或响应为错误,函数将直接返回原始响应,不进行过滤。
  • 字段支持点号分隔的嵌套路径(如 'user.name'),并自动处理父字段包含子字段的情况。
  • 函数内部调用 _rest_array_intersect_key_recursive() 进行递归键比较,确保数据结构的正确裁剪。

📄 原文内容

Filters the REST API response to include only an allow-listed set of response object fields.

Parameters

$responseWP_REST_Responserequired
Current response being served.
$serverWP_REST_Serverrequired
ResponseHandler instance (usually WP_REST_Server).
$requestWP_REST_Requestrequired
The request that was used to make current response.

Return

WP_REST_Response Response to be served, trimmed down to contain a subset of fields.

Source

function rest_filter_response_fields( $response, $server, $request ) {
	if ( ! isset( $request['_fields'] ) || $response->is_error() ) {
		return $response;
	}

	$data = $response->get_data();

	$fields = wp_parse_list( $request['_fields'] );

	if ( 0 === count( $fields ) ) {
		return $response;
	}

	// Trim off outside whitespace from the comma delimited list.
	$fields = array_map( 'trim', $fields );

	// Create nested array of accepted field hierarchy.
	$fields_as_keyed = array();
	foreach ( $fields as $field ) {
		$parts = explode( '.', $field );
		$ref   = &$fields_as_keyed;
		while ( count( $parts ) > 1 ) {
			$next = array_shift( $parts );
			if ( isset( $ref[ $next ] ) && true === $ref[ $next ] ) {
				// Skip any sub-properties if their parent prop is already marked for inclusion.
				break 2;
			}
			$ref[ $next ] = isset( $ref[ $next ] ) ? $ref[ $next ] : array();
			$ref          = &$ref[ $next ];
		}
		$last         = array_shift( $parts );
		$ref[ $last ] = true;
	}

	if ( wp_is_numeric_array( $data ) ) {
		$new_data = array();
		foreach ( $data as $item ) {
			$new_data[] = _rest_array_intersect_key_recursive( $item, $fields_as_keyed );
		}
	} else {
		$new_data = _rest_array_intersect_key_recursive( $data, $fields_as_keyed );
	}

	$response->set_data( $new_data );

	return $response;
}

Changelog

Version Description
4.8.0 Introduced.