深入理解 WordPress `rest_query_vars` 过滤器源码:如何增加自定义查询参数以扩展 REST API。

各位观众老爷,晚上好!我是你们的老朋友,今天咱们来聊聊 WordPress REST API 扩展的一个非常实用,但也容易被忽略的技巧:如何利用 rest_query_vars 过滤器,往 REST API 里塞入我们自定义的查询参数,让它变得更加灵活,更加强大!

开场白:REST API 界的“暗度陈仓”

话说 WordPress REST API 已经成为了现代 WordPress 开发的标配,它让我们能像玩积木一样,用各种 JavaScript 框架(React, Vue, Angular…)搭建前端,然后通过 API 获取 WordPress 后端的数据。

但是,原生的 REST API 提供的查询参数,有时候并不能满足我们所有的需求。比如说,我想根据文章的“颜色”来过滤文章,或者根据文章的某个自定义字段进行排序。这时候,我们就需要自己动手,扩展 REST API 的查询能力了。

rest_query_vars 过滤器,就是我们今天要用到的秘密武器。它可以让我们在不修改 WordPress 核心代码的情况下,悄无声息地往 REST API 的查询参数列表里添加我们自己的参数。这就像古代战争中的“暗度陈仓”,表面上风平浪静,实际上已经悄悄改变了战局。

第一部分:认识 rest_query_vars 过滤器

首先,我们要搞清楚 rest_query_vars 过滤器到底是个什么东西。简单来说,它是一个 WordPress 过滤器,允许我们修改 REST API 请求中允许使用的查询变量(query variables)。

  • 过滤器类型: 数组过滤器
  • 触发时机: 在 REST API 请求被处理之前,WordPress 会调用这个过滤器。
  • 作用: 修改 REST API 请求中允许的查询变量数组。

它的基本用法是这样的:

add_filter( 'rest_query_vars', 'my_custom_rest_query_vars' );

function my_custom_rest_query_vars( $query_vars ) {
    // 在这里修改 $query_vars 数组
    return $query_vars;
}

在这个代码片段中,my_custom_rest_query_vars 是我们自定义的函数,它接收一个 $query_vars 数组作为参数,这个数组包含了 WordPress 允许在 REST API 请求中使用的所有查询变量。我们可以在这个函数里,往 $query_vars 数组里添加我们自己的查询变量,然后返回修改后的数组。

第二部分:实战演练:添加自定义查询参数

接下来,我们来做一个实际的例子。假设我们有一个名为 color 的自定义字段,用于存储文章的颜色。我们希望能够通过 REST API,根据文章的颜色来过滤文章。

  1. 定义自定义查询参数

首先,我们需要定义一个自定义查询参数,比如说 article_color。这个参数将用于接收用户传递的文章颜色。

  1. 使用 rest_query_vars 过滤器添加参数

然后,我们使用 rest_query_vars 过滤器,将 article_color 添加到 REST API 允许的查询变量列表中。

add_filter( 'rest_query_vars', 'add_article_color_query_var' );

function add_article_color_query_var( $query_vars ) {
    $query_vars[] = 'article_color';
    return $query_vars;
}

这段代码非常简单,它只是往 $query_vars 数组里添加了一个名为 article_color 的元素。现在,我们就可以在 REST API 请求中使用 article_color 参数了。

  1. 处理自定义查询参数

接下来,我们需要处理用户传递的 article_color 参数。我们需要修改 WordPress 的查询逻辑,让它能够根据 article_color 参数来过滤文章。

这里,我们可以使用 pre_get_posts 动作钩子。

add_action( 'pre_get_posts', 'filter_articles_by_color' );

function filter_articles_by_color( $query ) {
    // 只在 REST API 请求中执行
    if ( ! is_admin() && $query->is_main_query() && isset( $_GET['article_color'] ) ) {
        $color = sanitize_text_field( $_GET['article_color'] );

        // 确保自定义字段存在
        if( get_field_object('color') ) {

        $query->set( 'meta_query', array(
            array(
                'key'     => 'color', // 自定义字段的名称
                'value'   => $color,
                'compare' => '=',
            ),
        ) );
      } else {
        error_log('自定义字段"color"不存在,请检查!');
      }
    }
}

这段代码做了以下几件事情:

  • 首先,它检查当前是否是 REST API 请求,并且是否传递了 article_color 参数。
  • 然后,它使用 sanitize_text_field 函数对 article_color 参数进行安全过滤,防止 XSS 攻击。
  • 最后,它使用 meta_query 参数,修改 WordPress 的查询逻辑,让它能够根据 article_color 参数来过滤文章。 如果自定义字段不存在,则打印错误日志,方便调试。

重要提示:安全性!安全性!安全性!

在使用 rest_query_vars 过滤器添加自定义查询参数时,一定要注意安全性。永远不要信任用户输入的数据。在使用用户输入的数据之前,一定要对其进行安全过滤,防止 XSS 攻击和 SQL 注入攻击。

第三部分:高级技巧:使用更复杂的查询逻辑

上面的例子非常简单,只是根据一个自定义字段的值来过滤文章。但是,在实际开发中,我们可能需要使用更复杂的查询逻辑。

比如说,我们可能需要根据多个自定义字段的值来过滤文章,或者需要使用更复杂的比较运算符(比如 LIKE, BETWEEN, IN 等)。

这时候,我们可以使用 meta_query 参数的更多高级用法。

  • 多个自定义字段

如果我们需要根据多个自定义字段的值来过滤文章,我们可以使用 meta_query 参数的嵌套数组。

$query->set( 'meta_query', array(
    'relation' => 'AND', // 或者 'OR'
    array(
        'key'     => 'color',
        'value'   => $color,
        'compare' => '=',
    ),
    array(
        'key'     => 'size',
        'value'   => $size,
        'compare' => '=',
    ),
) );

在这个代码片段中,我们使用了 meta_query 参数的嵌套数组,定义了两个查询条件。relation 参数指定了这两个查询条件之间的关系,可以是 AND(表示同时满足两个条件)或者 OR(表示满足其中一个条件)。

  • 更复杂的比较运算符

如果我们需要使用更复杂的比较运算符,我们可以在 meta_query 参数中指定 compare 参数。

$query->set( 'meta_query', array(
    array(
        'key'     => 'price',
        'value'   => array( 10, 20 ),
        'compare' => 'BETWEEN',
        'type'    => 'NUMERIC',
    ),
) );

在这个代码片段中,我们使用了 BETWEEN 比较运算符,表示 price 字段的值必须在 10 到 20 之间。type 参数指定了 price 字段的数据类型,这里是 NUMERIC(数字类型)。

常用的 compare 参数有:

运算符 描述
= 等于
!= 不等于
> 大于
>= 大于等于
< 小于
<= 小于等于
LIKE 类似,可以使用 % 作为通配符
NOT LIKE 不类似,可以使用 % 作为通配符
IN 在数组中
NOT IN 不在数组中
BETWEEN 在两个值之间 (需要提供一个包含两个值的数组)
NOT BETWEEN 不在两个值之间 (需要提供一个包含两个值的数组)
EXISTS 自定义字段存在 (value 留空)
NOT EXISTS 自定义字段不存在 (value 留空)

第四部分:更高级的用法:排序

除了过滤文章,我们还可以使用 rest_query_vars 过滤器,添加自定义的排序参数。

比如说,我们希望能够根据文章的某个自定义字段进行排序。

  1. 添加自定义排序参数

首先,我们需要添加一个自定义排序参数,比如说 orderby_color

add_filter( 'rest_query_vars', 'add_orderby_color_query_var' );

function add_orderby_color_query_var( $query_vars ) {
    $query_vars[] = 'orderby_color';
    return $query_vars;
}
  1. 处理自定义排序参数

然后,我们需要处理用户传递的 orderby_color 参数。

add_action( 'pre_get_posts', 'orderby_articles_by_color' );

function orderby_articles_by_color( $query ) {
    if ( ! is_admin() && $query->is_main_query() && isset( $_GET['orderby_color'] ) ) {
        $query->set( 'orderby', 'meta_value' );
        $query->set( 'meta_key', 'color' ); //自定义字段名
        $query->set( 'order', sanitize_text_field( $_GET['orderby_color'] ) ); //ASC 或 DESC
    }
}

这段代码做了以下几件事情:

  • 首先,它检查当前是否是 REST API 请求,并且是否传递了 orderby_color 参数。
  • 然后,它设置了 orderby 参数为 meta_value,表示按照自定义字段的值进行排序。
  • 接着,它设置了 meta_key 参数为 color,表示按照 color 自定义字段的值进行排序。
  • 最后,它设置了 order 参数为用户传递的 orderby_color 参数的值,表示排序方式(升序或降序)。

第五部分:代码示例:完整的代码

<?php
/**
 * Plugin Name: Custom REST API Query
 * Description: Adds custom query parameters to the WordPress REST API.
 * Version: 1.0.0
 * Author: Your Name
 */

// 添加自定义查询参数 'article_color'
add_filter( 'rest_query_vars', 'add_article_color_query_var' );

function add_article_color_query_var( $query_vars ) {
    $query_vars[] = 'article_color';
    return $query_vars;
}

// 处理自定义查询参数 'article_color'
add_action( 'pre_get_posts', 'filter_articles_by_color' );

function filter_articles_by_color( $query ) {
    if ( ! is_admin() && $query->is_main_query() && isset( $_GET['article_color'] ) ) {
        $color = sanitize_text_field( $_GET['article_color'] );
        // 确保自定义字段存在
        if( get_field_object('color') ) {

        $query->set( 'meta_query', array(
            array(
                'key'     => 'color',
                'value'   => $color,
                'compare' => '=',
            ),
        ) );
      } else {
        error_log('自定义字段"color"不存在,请检查!');
      }
    }
}

// 添加自定义排序参数 'orderby_color'
add_filter( 'rest_query_vars', 'add_orderby_color_query_var' );

function add_orderby_color_query_var( $query_vars ) {
    $query_vars[] = 'orderby_color';
    return $query_vars;
}

// 处理自定义排序参数 'orderby_color'
add_action( 'pre_get_posts', 'orderby_articles_by_color' );

function orderby_articles_by_color( $query ) {
    if ( ! is_admin() && $query->is_main_query() && isset( $_GET['orderby_color'] ) ) {
        $query->set( 'orderby', 'meta_value' );
        $query->set( 'meta_key', 'color' );
        $query->set( 'order', sanitize_text_field( $_GET['orderby_color'] ) );
    }
}

第六部分:调试技巧

如果你的代码没有按照预期工作,可以使用以下调试技巧:

  1. error_log() 函数

在关键代码处使用 error_log() 函数,将变量的值输出到 WordPress 的错误日志中。

  1. var_dump() 函数

使用 var_dump() 函数,打印变量的详细信息。

  1. Query Monitor 插件

安装 Query Monitor 插件,它可以帮助你分析 WordPress 的查询语句,找出问题所在。

第七部分:注意事项

  1. 性能问题

过度使用自定义查询参数可能会导致性能问题。请尽量避免使用复杂的查询逻辑,并对查询进行优化。

  1. 版本兼容性

在使用 rest_query_vars 过滤器时,请注意 WordPress 的版本兼容性。不同的 WordPress 版本,可能对 rest_query_vars 过滤器的行为有所不同。

  1. 代码组织

为了代码的可维护性,请将自定义查询参数相关的代码,封装到单独的函数或类中。

总结

rest_query_vars 过滤器是一个非常强大的工具,它可以让我们在不修改 WordPress 核心代码的情况下,扩展 REST API 的查询能力。但是,在使用 rest_query_vars 过滤器时,一定要注意安全性,并对查询进行优化,避免性能问题。

好了,今天的讲座就到这里。希望大家能够掌握 rest_query_vars 过滤器的用法,让 WordPress REST API 更加强大,更加灵活! 谢谢大家!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注