阐述 WordPress `rest_query_vars` 过滤器源码:如何增加自定义的查询参数以扩展 REST API。

嘿,各位代码爱好者们!今天咱们来聊聊 WordPress REST API 的一个神奇角落:rest_query_vars 过滤器。这玩意儿就像REST API的后门,能让你悄咪咪地塞进去一些自定义的查询参数,扩展它的功能。想象一下,就像给你的汽车加装了个火箭推进器,嗖的一下就飞起来了!当然,前提是你得知道怎么用这个“推进器”。

开场白:REST API 的查询参数,你了解多少?

在深入 rest_query_vars 之前,咱们先回顾一下 REST API 查询参数的基础知识。简单来说,查询参数就是你通过 URL 传递给 API 的信息,用来过滤、排序、分页等等。比如:

https://example.com/wp-json/wp/v2/posts?per_page=10&search=WordPress

这里的 per_pagesearch 就是查询参数。WordPress 默认支持一些常用的查询参数,比如 per_page(每页数量)、search(搜索关键词)、orderby(排序方式)等等。

但是,有时候我们想要实现一些更复杂、更个性化的功能,默认的查询参数就不够用了。这时候,rest_query_vars 就派上用场了。

第一部分:rest_query_vars 过滤器:你的秘密武器

rest_query_vars 是一个 WordPress 过滤器,它允许你修改 REST API 请求中允许使用的查询变量列表。 简单来说,就是告诉 WordPress: “嘿,除了默认的那些,我还想让API支持这些查询参数!”

1.1 源码剖析:rest_query_vars 的真面目

这个过滤器在 WordPress 核心代码的 WP_REST_Request::get_query_params() 方法中被调用。 咱们不用深究 WP_REST_Request 类的细节,只需要知道在处理 API 请求时,WordPress 会调用这个方法来获取允许使用的查询参数列表。

核心代码片段(简化版):

// wp-includes/rest-api/class-wp-rest-request.php

public function get_query_params() {
    $params = array(
        'context'  => array(
            'default' => 'view',
            'type'    => 'string',
        ),
        // ... other default parameters ...
    );

    /**
     * Filters the allowed query parameters for a REST request.
     *
     * @since 4.7.0
     *
     * @param array $params Allowed query parameters.
     */
    $params = apply_filters( 'rest_query_vars', $params );

    return $params;
}

看到 apply_filters( 'rest_query_vars', $params ) 没? 这就是 rest_query_vars 发挥作用的地方。 WordPress 会把默认的查询参数数组 $params 传递给这个过滤器,然后你可以对这个数组进行修改,添加你自己的查询参数。

1.2 如何使用 rest_query_vars?(敲黑板!)

使用 rest_query_vars 非常简单,只需要在你的主题的 functions.php 文件或者自定义插件中添加一个函数,然后用 add_filter() 函数把它挂载到 rest_query_vars 过滤器上。

add_filter( 'rest_query_vars', 'my_custom_rest_query_vars' );

function my_custom_rest_query_vars( $query_vars ) {
    // 在这里添加你的自定义查询参数
    $query_vars['my_custom_param'] = 'my_custom_param'; // 将自定义参数添加到白名单中
    return $query_vars;
}

上面的代码片段是最简单的例子。 它只是简单地把 my_custom_param 添加到允许的查询参数列表中。 注意,这里只是告诉 WordPress 允许使用这个参数, 还没告诉它这个参数应该如何处理。

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

光说不练假把式,咱们来几个实战例子,演示如何添加自定义查询参数,并让它们真正发挥作用。

2.1 例子 1:按颜色筛选文章

假设我们想添加一个 color 查询参数,用来筛选文章,只显示包含特定颜色的文章。

步骤 1:添加 colorrest_query_vars

add_filter( 'rest_query_vars', 'my_custom_rest_query_vars' );

function my_custom_rest_query_vars( $query_vars ) {
    $query_vars['color'] = 'color';
    return $query_vars;
}

步骤 2:修改主查询 (pre_get_posts)

现在 WordPress 知道 color 是一个有效的查询参数了,但是它还不知道该如何处理它。我们需要修改主查询,让它根据 color 参数来筛选文章。

add_action( 'pre_get_posts', 'my_custom_pre_get_posts' );

function my_custom_pre_get_posts( $query ) {
    // 确保只在 REST API 请求中执行
    if ( ! is_admin() && $query->is_main_query() && defined( 'REST_REQUEST' ) && REST_REQUEST ) {
        $color = isset( $_GET['color'] ) ? sanitize_text_field( $_GET['color'] ) : '';

        if ( ! empty( $color ) ) {
            // 使用自定义字段来存储文章颜色
            $query->set( 'meta_query', array(
                array(
                    'key'     => 'article_color', // 自定义字段名称
                    'value'   => $color,
                    'compare' => '=',
                ),
            ));
        }
    }
}

这段代码做了什么?

  • is_admin() 确保这段代码只在前端执行,避免影响后台。
  • $query->is_main_query() 确保我们只修改主查询,而不是其他查询。
  • defined( 'REST_REQUEST' ) && REST_REQUEST 确保这段代码只在 REST API 请求中执行。
  • isset( $_GET['color'] ) 检查 color 查询参数是否存在。
  • sanitize_text_field( $_GET['color'] )color 参数进行安全过滤,防止 XSS 攻击。
  • $query->set( 'meta_query', ... ) 修改主查询,添加一个 meta_query,根据 article_color 自定义字段来筛选文章。

重要提示:

  • 你需要先创建一个名为 article_color 的自定义字段,并在文章中设置相应的颜色值。
  • 代码中的 'article_color' 只是一个例子,你可以使用任何你喜欢的自定义字段名称。
  • sanitize_text_field() 函数可以防止简单的 XSS 攻击,但是对于更复杂的攻击,你可能需要使用更强大的安全过滤措施。

现在,你可以通过以下 URL 来筛选文章:

https://example.com/wp-json/wp/v2/posts?color=red

这个 URL 会返回所有 article_color 自定义字段值为 red 的文章。

2.2 例子 2:按作者年龄筛选文章

这个例子稍微复杂一点,我们需要根据作者的年龄来筛选文章。

步骤 1:添加 author_agerest_query_vars

add_filter( 'rest_query_vars', 'my_custom_rest_query_vars' );

function my_custom_rest_query_vars( $query_vars ) {
    $query_vars['author_age'] = 'author_age';
    return $query_vars;
}

步骤 2:修改主查询 (pre_get_posts)

add_action( 'pre_get_posts', 'my_custom_pre_get_posts' );

function my_custom_pre_get_posts( $query ) {
    if ( ! is_admin() && $query->is_main_query() && defined( 'REST_REQUEST' ) && REST_REQUEST ) {
        $author_age = isset( $_GET['author_age'] ) ? intval( $_GET['author_age'] ) : 0;

        if ( $author_age > 0 ) {
            // 获取所有符合年龄要求的作者 ID
            $user_query = new WP_User_Query( array(
                'meta_query' => array(
                    array(
                        'key'     => 'author_age', // 自定义用户字段
                        'value'   => $author_age,
                        'compare' => '=',
                        'type'    => 'NUMERIC',
                    ),
                ),
                'fields' => 'ID', // 只获取用户 ID
            ) );

            $author_ids = $user_query->get_results();

            if ( ! empty( $author_ids ) ) {
                // 根据作者 ID 筛选文章
                $query->set( 'author__in', $author_ids );
            } else {
                // 如果没有符合条件的作者,则不返回任何文章
                $query->set( 'post__in', array(0) ); // 设置一个不存在的 ID
            }
        }
    }
}

这段代码做了什么?

  • intval( $_GET['author_age'] )author_age 参数转换为整数,增加安全性。
  • WP_User_Query 用于查询符合年龄要求的作者。
  • 'author_age' 是一个自定义用户字段,你需要先在用户个人资料中添加这个字段,并设置相应的年龄值。
  • $query->set( 'author__in', $author_ids ) 根据作者 ID 筛选文章。
  • 如果找不到符合条件的作者,则设置 post__in 为一个不存在的 ID,确保不返回任何文章。

现在,你可以通过以下 URL 来筛选文章:

https://example.com/wp-json/wp/v2/posts?author_age=30

这个 URL 会返回所有由年龄为 30 岁的作者撰写的文章。

表格总结:两个例子的对比

功能 查询参数 自定义字段 使用到的函数/类 关键步骤
按颜色筛选文章 color article_color pre_get_posts, sanitize_text_field 添加 meta_query,根据文章自定义字段筛选文章
按作者年龄筛选文章 author_age author_age pre_get_posts, WP_User_Query, intval 使用 WP_User_Query 获取符合条件的作者 ID,然后根据作者 ID 筛选文章

第三部分:注意事项和最佳实践

虽然 rest_query_vars 很强大,但是在使用时也需要注意一些事项,避免踩坑。

3.1 安全第一!

  • 永远要对查询参数进行安全过滤! 使用 sanitize_text_field(), intval(), absint(), floatval() 等函数,根据参数类型进行相应的过滤,防止 XSS 攻击和 SQL 注入。
  • 不要信任用户输入! 永远假设用户会输入恶意数据,并做好相应的防范措施。

3.2 性能优化

  • 避免在 pre_get_posts 中执行复杂的查询! 如果你需要执行复杂的查询,可以考虑使用 WP_Query 类,并缓存查询结果,提高性能。
  • 尽量使用索引! 如果你的自定义字段经常被用于查询,可以考虑为它们添加索引,加快查询速度。

3.3 代码规范

  • 为你的自定义查询参数添加详细的注释! 方便自己和其他开发者理解代码。
  • 使用有意义的参数名称! 避免使用过于简单或者含糊不清的参数名称。
  • 将自定义代码封装成函数或者类! 提高代码的可维护性和可重用性。

3.4 兼容性

  • 测试你的代码在不同的 WordPress 版本和主题下的兼容性! 确保你的代码能够正常运行。
  • 注意与其他插件的冲突! 避免与其他插件使用相同的查询参数名称。

第四部分:总结与展望

rest_query_vars 过滤器是扩展 WordPress REST API 的一个强大工具。 它可以让你添加自定义的查询参数,实现各种各样的个性化功能。 但是,在使用时一定要注意安全、性能和代码规范,避免踩坑。

希望今天的讲座能帮助你更好地理解和使用 rest_query_vars 过滤器。 掌握了这个技巧,你就可以像个魔法师一样,自由地操控 REST API,让它为你所用!

记住,代码的世界充满乐趣,大胆尝试,不断学习,你也能成为一名优秀的 WordPress 开发者! 咱们下期再见!

发表回复

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