剖析 `wp_set_current_user()` 函数的源码，它如何设置全局变量 `$current_user`？

admin
Thu, 07 Aug 2025 10:26:57 +0000
PHP, current, user, 源码

大家好！欢迎来到今天的“WordPress源码扒皮”讲座！ 今天我们要聊聊WordPress里一个非常核心的函数：wp_set_current_user()。这个函数的重要性，就好比一个国家的总统，负责确定当前是谁在操作WordPress，权限是什么，等等。 咱们要把它扒个底朝天，看看它是怎么把全局变量 $current_user 给安排上的。 一、wp_set_current_user() 是何方神圣？ 简单来说，wp_set_current_user() 的作用就是设置当前用户。它接受一个用户ID作为参数，然后根据这个ID去数据库里捞取用户数据，并把这些数据填充到一个叫做 $current_user 的全局变量里。有了 $current_user，WordPress 才能知道当前用户是谁，才能进行权限判断、个性化显示等等操作。 二、源码剖析：一步一步解开它的面纱 咱们直接上代码，边看边解释： /** * Sets the current user. * * @since 2.0.0 * * @global WP_User $current_user * * @param int|W …

继续阅读“剖析 `wp_set_current_user()` 函数的源码，它如何设置全局变量 `$current_user`？”

The post 剖析 `wp_set_current_user()` 函数的源码，它如何设置全局变量 `$current_user`？ first appeared on 智猿学院-前后端，数据库，人工智能，云计算等领域前沿技术讲座.

大家好！欢迎来到今天的“WordPress源码扒皮”讲座！

今天我们要聊聊WordPress里一个非常核心的函数：wp_set_current_user()。这个函数的重要性，就好比一个国家的总统，负责确定当前是谁在操作WordPress，权限是什么，等等。 咱们要把它扒个底朝天，看看它是怎么把全局变量 $current_user 给安排上的。

一、wp_set_current_user() 是何方神圣？

简单来说，wp_set_current_user() 的作用就是设置当前用户。它接受一个用户ID作为参数，然后根据这个ID去数据库里捞取用户数据，并把这些数据填充到一个叫做 $current_user 的全局变量里。有了 $current_user，WordPress 才能知道当前用户是谁，才能进行权限判断、个性化显示等等操作。

二、源码剖析：一步一步解开它的面纱

咱们直接上代码，边看边解释：

/**
 * Sets the current user.
 *
 * @since 2.0.0
 *
 * @global WP_User $current_user
 *
 * @param int|WP_User $id User ID.
 */
function wp_set_current_user( $id ) {
    global $current_user;

    if ( ! ( $id instanceof WP_User ) ) {
        $id = (int) $id; // 确保是整数
    }

    if ( empty( $id ) ) {
        $current_user = new WP_User( 0 ); // 设置为匿名用户
        return;
    }

    if ( is_object( $id ) && isset( $id->ID ) ) {
        $id = $id->ID; // 如果传入的是 WP_User 对象，提取 ID
    }

    if ( ! ( $current_user instanceof WP_User ) ) {
        $current_user = new WP_User();
    }

    if ( get_current_user_id() == $id && isset( $current_user->ID ) && ( (int) $current_user->ID === (int) $id ) ) {
        return; // 如果已经是当前用户，直接返回
    }

    $current_user = get_userdata( $id ); // 从数据库获取用户数据

    if ( ! $current_user ) {
        $current_user = new WP_User( 0 ); // 如果用户不存在，设置为匿名用户
        return;
    }

    wp_cache_set( 'current_user', $current_user, 'users' ); // 缓存当前用户

    do_action( 'set_current_user', $current_user ); // 触发一个钩子，方便扩展
}

咱们来一行一行地解读：

1. function wp_set_current_user( $id ) {: 定义函数，接受一个参数 $id，这就是我们要设置的用户的ID。

2. global $current_user;: 声明 $current_user 为全局变量。 这意味着我们在函数内部可以访问和修改全局作用域中的 $current_user 变量。 如果没有这句，函数内部的 $current_user 只是一个局部变量，修改它不会影响全局变量。

3. if ( ! ( $id instanceof WP_User ) ) { $id = (int) $id; }: 检查 $id 是否是 WP_User 对象。如果不是，就强制转换为整数。 这样做是为了确保 $id 是一个有效的用户ID，方便后续操作。

4. if ( empty( $id ) ) { $current_user = new WP_User( 0 ); return; }: 如果 $id 为空，则创建一个匿名用户。 new WP_User(0) 会创建一个 WP_User 对象，其ID为0，表示匿名用户或未登录用户。 然后函数直接返回，不再执行后续操作。

5. if ( is_object( $id ) && isset( $id->ID ) ) { $id = $id->ID; }: 如果 $id 是一个 WP_User 对象，并且包含 ID 属性，则提取出 ID 属性的值。 这样做的目的是为了兼容传入 WP_User 对象的情况，直接使用对象的 ID。

6. if ( ! ( $current_user instanceof WP_User ) ) { $current_user = new WP_User(); }: 检查 $current_user 是否是 WP_User 的实例。如果不是，就创建一个新的 WP_User 对象。 这通常发生在第一次调用 wp_set_current_user() 的时候，$current_user 还没有被初始化。

7. if ( get_current_user_id() == $id && isset( $current_user->ID ) && ( (int) $current_user->ID === (int) $id ) ) { return; }: 这是一个优化措施。如果当前用户已经是我们要设置的用户，就直接返回，不再重复设置。 get_current_user_id() 函数会获取当前用户的ID。 isset( $current_user->ID ) 确保 $current_user 对象已经被正确初始化，并且包含 ID 属性。

8. $current_user = get_userdata( $id );: 这是最核心的一步。使用 get_userdata() 函数根据 $id 从数据库中获取用户数据，并赋值给 $current_user。 get_userdata() 函数会返回一个 WP_User 对象，包含了用户的各种信息，如用户名、邮箱、角色等等。

9. if ( ! $current_user ) { $current_user = new WP_User( 0 ); return; }: 如果 get_userdata() 没有找到对应的用户（例如，ID不存在），则创建一个匿名用户。 这是一种安全措施，防止出现未知的用户状态。

10. wp_cache_set( 'current_user', $current_user, 'users' );: 将当前用户对象缓存起来，方便下次使用。 wp_cache_set() 函数是WordPress的缓存机制，可以提高性能。

11. do_action( 'set_current_user', $current_user );: 触发一个名为 set_current_user 的动作钩子。 这允许其他插件或主题在设置当前用户后执行一些自定义操作。 比如，可以记录用户登录日志，或者更新用户的某些状态。

三、$current_user 到底存了些啥？

$current_user 是一个 WP_User 对象，它包含了关于当前用户的所有信息。 我们可以通过访问这个对象的属性来获取用户的各种信息。

属性名 | 数据类型 | 描述
ID | int | 用户ID
user_login | string | 用户名
user_pass | string | 用户密码（通常是哈希过的）
user_nicename | string | 用户昵称，用于友好的URL
user_email | string | 用户邮箱
user_url | string | 用户个人网站URL
user_registered | string | 用户注册时间
user_activation_key | string | 用户激活密钥（通常用于注册验证）
user_status | string | 用户状态（例如，0表示正常，1表示被禁止）
display_name | string | 显示名称（可以是昵称或其他设置）
roles | array | 用户角色（例如，administrator、editor、author）
caps | array | 用户权限（由角色决定，也可以单独赋予）
allcaps | array | 用户所有权限（包括角色权限和单独赋予的权限）
filter | string | 用于过滤数据的上下文

例子：

global $current_user;

if ( is_user_logged_in() ) {
    echo '你好，' . $current_user->display_name . '！';
echo ' 你的邮箱是：' . $current_user->user_email;

    if ( in_array( 'administrator', $current_user->roles ) ) {
echo ' 你是管理员！';
    }
} else {
    echo '您尚未登录。';
}

四、wp_set_current_user() 在哪里被调用？

wp_set_current_user() 函数在WordPress的很多地方都会被调用，主要是在以下场景：

用户登录： 当用户成功登录后，wp_set_current_user() 会被调用，将当前用户设置为已登录的用户。

后台管理页面： 在后台管理页面，wp_set_current_user() 会被调用，确保当前用户是经过身份验证的用户。

REST API： 在使用REST API时，wp_set_current_user() 会被调用，根据认证信息设置当前用户。

插件和主题： 插件和主题也可以调用 wp_set_current_user()，例如，在处理自定义登录逻辑时。

五、注意事项和最佳实践

安全性： wp_set_current_user() 是一个非常敏感的函数，因为它直接影响到用户的身份和权限。 因此，必须谨慎使用，确保只有在经过充分验证的情况下才能调用它。 否则，可能会导致安全漏洞。

不要滥用： 不要随意调用 wp_set_current_user()，特别是不要在不必要的时候修改当前用户。 频繁修改当前用户可能会导致性能问题和不可预测的行为。

使用 is_user_logged_in() 判断用户是否登录： 在访问 $current_user 之前，务必使用 is_user_logged_in() 函数判断用户是否已经登录。 否则，如果用户未登录，访问 $current_user 可能会导致错误。

使用钩子： 如果需要在设置当前用户后执行一些自定义操作，可以使用 set_current_user 动作钩子，而不要直接修改 wp_set_current_user() 函数的代码。

六、get_userdata()：幕后英雄

既然提到了 wp_set_current_user()，就不得不提一下它背后默默奉献的 get_userdata() 函数。 get_userdata() 负责从数据库中获取用户数据，并返回一个 WP_User 对象。

/**
 * Retrieve user info by user ID.
 *
 * @since 2.0.0
 *
 * @param int|object $user User ID or WP_User object
 * @return WP_User|false WP_User object on success, false on failure.
 */
function get_userdata( $user ) {
    if ( ! is_numeric( $user ) && ! ( $user instanceof WP_User ) ) {
        return false;
    }

    $user_id = ( $user instanceof WP_User ) ? $user->ID : (int) $user;

    $user = get_user( $user_id ); // 使用 get_user() 函数获取用户对象

    if ( ! $user ) {
        return false;
    }

    return $user;
}

实际上，get_userdata() 内部调用了 get_user() 函数。 get_user() 会首先检查缓存，如果缓存中存在用户信息，则直接返回缓存的数据。 否则，它会查询数据库，创建一个 WP_User 对象，并将其添加到缓存中。

七、总结

wp_set_current_user() 函数是WordPress中一个至关重要的函数，它负责设置当前用户，并将其信息存储在全局变量 $current_user 中。 理解这个函数的工作原理对于开发WordPress插件和主题至关重要。 通过深入剖析源码，我们了解了 wp_set_current_user() 是如何设置 $current_user 的，以及它在WordPress生态系统中的作用。 希望今天的讲座能帮助大家更好地理解WordPress的底层机制。

八、思考题

1. 如果我直接修改 $current_user 全局变量，而不是使用 wp_set_current_user() 函数，会有什么潜在问题？

2. set_current_user 动作钩子有哪些常见的应用场景？

3. 如果我想在用户登录后，立即更新用户的一些自定义信息（例如，上次登录时间），应该如何实现？

今天的讲座就到这里，谢谢大家！ 希望大家继续深入研究WordPress源码，成为真正的WordPress专家！