探讨 WP_User_Query 类如何构建动态过滤条件

WP_User_Query:构建动态用户过滤条件的艺术

大家好!今天我们来深入探讨 WordPress 中一个非常强大的类:WP_User_Query。它的主要作用是允许我们根据各种不同的条件,动态地查询和获取 WordPress 用户信息。理解 WP_User_Query 的构建方式,以及如何灵活地运用它的参数,对于开发涉及用户管理的 WordPress 插件或主题至关重要。

WP_User_Query 的基本结构

首先,我们来看一下 WP_User_Query 的基本使用方法。最简单的形式是创建一个 WP_User_Query 对象,并执行查询:

$args = array(); // 查询参数,稍后详细讲解
$user_query = new WP_User_Query( $args );

if ( ! empty( $user_query->get_results() ) ) {
    foreach ( $user_query->get_results() as $user ) {
        echo '<p>' . esc_html( $user->display_name ) . '</p>';
    }
} else {
    echo '<p>没有找到符合条件的用户。</p>';
}

这段代码创建了一个 $user_query 对象,并传入一个空的 $args 数组。这意味着查询将返回所有用户。然后,我们检查查询结果是否为空,如果不是,则遍历结果,并输出每个用户的显示名称。

关键在于 $args 数组,它决定了查询的行为。WP_User_Query 提供了丰富的参数,允许我们构建非常具体的查询条件。

常用查询参数详解

接下来,我们详细了解一些常用的查询参数,以及如何使用它们来构建动态的过滤条件。

1. searchsearch_columns

search 参数允许我们根据指定的字符串搜索用户。search_columns 参数则指定了搜索的字段。

$args = array(
    'search'         => '*john*', // 搜索包含 "john" 的用户
    'search_columns' => array( 'user_login', 'user_email', 'display_name' ), // 在这些字段中搜索
);
$user_query = new WP_User_Query( $args );

上面的代码会在 user_login, user_emaildisplay_name 这三个字段中搜索包含 "john" 的用户。注意 search 参数中的通配符 *

2. includeexclude

include 参数允许我们只获取指定 ID 的用户,而 exclude 参数则允许我们排除指定 ID 的用户。

$args = array(
    'include' => array( 1, 2, 3 ), // 只获取 ID 为 1, 2, 3 的用户
);
$user_query = new WP_User_Query( $args );

$args = array(
    'exclude' => array( 4, 5, 6 ), // 排除 ID 为 4, 5, 6 的用户
);
$user_query = new WP_User_Query( $args );

3. rolerole__in, role__not_in

role 参数允许我们根据用户角色过滤用户。role__inrole__not_in 允许我们指定一个角色数组。

$args = array(
    'role' => 'editor', // 只获取角色为 editor 的用户
);
$user_query = new WP_User_Query( $args );

$args = array(
    'role__in' => array( 'editor', 'author' ), // 获取角色为 editor 或 author 的用户
);
$user_query = new WP_User_Query( $args );

$args = array(
    'role__not_in' => array( 'subscriber', 'contributor' ), // 排除角色为 subscriber 或 contributor 的用户
);
$user_query = new WP_User_Query( $args );

4. meta_query

meta_query 是一个非常强大的参数,它允许我们根据用户元数据(自定义字段)过滤用户。

meta_query 参数接受一个数组,每个元素代表一个元数据查询条件。每个查询条件本身也是一个数组,包含以下键:

  • key: 元数据的键名。
  • value: 元数据的值。
  • compare: 比较运算符(例如 =', !=', >', <', LIKE, NOT LIKE, IN, NOT IN, BETWEEN, NOT BETWEEN, EXISTS, NOT EXISTS)。
  • type: 元数据值的类型(例如 NUMERIC, BINARY, CHAR, DATE, DATETIME, DECIMAL, SIGNED, UNSIGNED)。
$args = array(
    'meta_query' => array(
        array(
            'key'     => 'city', // 元数据键名为 "city"
            'value'   => 'New York', // 元数据值为 "New York"
            'compare' => '=', // 比较运算符为等于
        ),
    ),
);
$user_query = new WP_User_Query( $args );

上面的代码会获取所有 city 元数据值为 "New York" 的用户。

我们可以组合多个元数据查询条件:

$args = array(
    'meta_query' => array(
        'relation' => 'AND', // 多个条件之间的关系,可以是 'AND' 或 'OR'
        array(
            'key'     => 'city',
            'value'   => 'New York',
            'compare' => '=',
        ),
        array(
            'key'     => 'age',
            'value'   => 30,
            'compare' => '>',
            'type'    => 'NUMERIC',
        ),
    ),
);
$user_query = new WP_User_Query( $args );

上面的代码会获取所有 city 元数据值为 "New York" 且 age 元数据值大于 30 的用户。'relation' => 'AND' 指定了两个条件必须同时满足。

5. orderbyorder

orderby 参数允许我们指定排序的字段,order 参数允许我们指定排序的顺序。

$args = array(
    'orderby' => 'login', // 根据用户名排序
    'order'   => 'ASC', // 升序排列
);
$user_query = new WP_User_Query( $args );

$args = array(
    'orderby' => 'post_count', // 根据文章数量排序
    'order'   => 'DESC', // 降序排列
);
$user_query = new WP_User_Query( $args );

$args = array(
    'orderby' => 'meta_value', // 根据元数据排序 (需要配合 'meta_key' 参数)
    'meta_key' => 'age',
    'order'   => 'ASC',
);
$user_query = new WP_User_Query( $args );

注意,当 orderby 设置为 meta_valuemeta_value_num 时,必须同时指定 meta_key 参数。

6. numberoffset

number 参数允许我们指定返回的用户数量,offset 参数允许我们指定起始位置。这两个参数通常用于分页。

$args = array(
    'number' => 10, // 只返回 10 个用户
    'offset' => 20, // 从第 21 个用户开始
);
$user_query = new WP_User_Query( $args );

构建动态过滤条件的实践

现在,我们来看几个实际的例子,演示如何使用 WP_User_Query 构建动态的过滤条件。

例 1:根据用户输入的关键词和角色过滤用户

假设我们有一个表单,允许用户输入关键词和选择角色,然后根据这些条件过滤用户。

// 获取用户输入的关键词和选择的角色
$keyword = isset( $_GET['keyword'] ) ? sanitize_text_field( $_GET['keyword'] ) : '';
$role    = isset( $_GET['role'] ) ? sanitize_text_field( $_GET['role'] ) : '';

$args = array();

if ( ! empty( $keyword ) ) {
    $args['search']         = '*' . $keyword . '*';
    $args['search_columns'] = array( 'user_login', 'user_email', 'display_name' );
}

if ( ! empty( $role ) ) {
    $args['role'] = $role;
}

$user_query = new WP_User_Query( $args );

// 显示查询结果
if ( ! empty( $user_query->get_results() ) ) {
    echo '<ul>';
    foreach ( $user_query->get_results() as $user ) {
        echo '<li>' . esc_html( $user->display_name ) . '</li>';
    }
    echo '</ul>';
} else {
    echo '<p>没有找到符合条件的用户。</p>';
}

这段代码首先获取用户输入的关键词和选择的角色。然后,根据这些条件构建 $args 数组。如果用户输入了关键词,则设置 searchsearch_columns 参数。如果用户选择了角色,则设置 role 参数。最后,执行查询并显示结果.

例 2:根据自定义字段范围过滤用户

假设我们有一个自定义字段 age,我们需要根据用户选择的年龄范围过滤用户。

// 获取用户选择的年龄范围
$min_age = isset( $_GET['min_age'] ) ? intval( $_GET['min_age'] ) : 0;
$max_age = isset( $_GET['max_age'] ) ? intval( $_GET['max_age'] ) : 100;

$args = array(
    'meta_query' => array(
        array(
            'key'     => 'age',
            'value'   => array( $min_age, $max_age ),
            'compare' => 'BETWEEN',
            'type'    => 'NUMERIC',
        ),
    ),
);

$user_query = new WP_User_Query( $args );

// 显示查询结果
if ( ! empty( $user_query->get_results() ) ) {
    echo '<ul>';
    foreach ( $user_query->get_results() as $user ) {
        echo '<li>' . esc_html( $user->display_name ) . ' (Age: ' . get_user_meta( $user->ID, 'age', true ) . ')</li>';
    }
    echo '</ul>';
} else {
    echo '<p>没有找到符合条件的用户。</p>';
}

这段代码首先获取用户选择的年龄范围。然后,使用 meta_query 参数构建查询条件,使用 BETWEEN 比较运算符来过滤指定年龄范围内的用户。

例 3:结合 pre_user_query 钩子修改查询

除了直接使用 $args 数组,我们还可以使用 pre_user_query 钩子来修改 WP_User_Query 对象。这允许我们在查询执行之前,动态地修改查询参数。

add_action( 'pre_user_query', 'my_custom_user_query' );

function my_custom_user_query( $query ) {
    // 只允许管理员查看所有用户
    if ( ! current_user_can( 'administrator' ) ) {
        $current_user_id = get_current_user_id();
        $query->query_vars['include'] = array( $current_user_id ); // 只获取当前用户
    }
}

这段代码使用 pre_user_query 钩子,在查询执行之前,检查当前用户是否是管理员。如果不是,则将查询参数 include 设置为当前用户的 ID,这意味着非管理员用户只能查看自己的信息。

性能注意事项

在使用 WP_User_Query 时,需要注意性能问题。特别是当使用 meta_query 进行复杂的查询时,可能会导致数据库查询效率降低。

以下是一些提高 WP_User_Query 性能的建议:

  • 尽量使用索引: 如果经常根据某个元数据字段进行查询,可以考虑为该字段添加索引。
  • 避免复杂的 meta_query 尽量简化 meta_query 的结构,避免使用过多的嵌套和复杂的比较运算符。
  • 使用缓存: 对于查询结果不经常变化的情况,可以使用缓存来提高性能。可以使用 WordPress 的对象缓存 API 或其他缓存插件。
  • 限制返回的用户数量: 如果只需要获取部分用户,可以使用 number 参数来限制返回的用户数量。

总结不同参数的用法

参数 描述 示例
search 搜索用户。可以使用通配符 * 'search' => '*john*'
search_columns 指定搜索的字段。 'search_columns' => array( 'user_login', 'user_email' )
include 只获取指定 ID 的用户。 'include' => array( 1, 2, 3 )
exclude 排除指定 ID 的用户。 'exclude' => array( 4, 5, 6 )
role 只获取指定角色的用户。 'role' => 'editor'
role__in 获取指定角色数组中的用户。 'role__in' => array( 'editor', 'author' )
role__not_in 排除指定角色数组中的用户。 'role__not_in' => array( 'subscriber', 'contributor' )
meta_query 根据用户元数据过滤用户。 'meta_query' => array( array( 'key' => 'city', 'value' => 'New York', 'compare' => '=' ) )
orderby 指定排序的字段。可以是 'ID', 'login', 'nicename', 'email', 'url', 'registered', 'display_name', 'post_count', 'meta_value', 'meta_value_num' 'orderby' => 'login'
order 指定排序的顺序。可以是 'ASC'(升序)或 'DESC'(降序)。 'order' => 'ASC'
number 指定返回的用户数量。 'number' => 10
offset 指定起始位置。 'offset' => 20
fields 指定返回的字段。可以是 'ID', 'user_login', 'user_pass', 'user_nicename', 'user_email', 'user_url', 'user_registered', 'user_activation_key', 'user_status', 'display_name', 'spam', 'deleted', 或者 'all' (返回所有字段), 或者一个字段数组。 默认是返回包含所有字段的 WP_User 对象。使用 'ID' 可以显著提高性能。 'fields' => 'ID'

掌握 WP_User_Query 是关键

WP_User_Query 是一个强大且灵活的工具,可以帮助我们高效地查询和管理 WordPress 用户。通过掌握它的各种参数和使用技巧,我们可以构建各种动态的过滤条件,满足不同的需求。希望今天的讲解能够帮助大家更好地理解和使用 WP_User_Query

发表回复

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