大家好!欢迎来到今天的“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 ); // 触发一个钩子,方便扩展
}
咱们来一行一行地解读:
-
function wp_set_current_user( $id ) {
: 定义函数,接受一个参数$id
,这就是我们要设置的用户的ID。 -
global $current_user;
: 声明$current_user
为全局变量。 这意味着我们在函数内部可以访问和修改全局作用域中的$current_user
变量。 如果没有这句,函数内部的$current_user
只是一个局部变量,修改它不会影响全局变量。 -
if ( ! ( $id instanceof WP_User ) ) { $id = (int) $id; }
: 检查$id
是否是WP_User
对象。如果不是,就强制转换为整数。 这样做是为了确保$id
是一个有效的用户ID,方便后续操作。 -
if ( empty( $id ) ) { $current_user = new WP_User( 0 ); return; }
: 如果$id
为空,则创建一个匿名用户。new WP_User(0)
会创建一个WP_User
对象,其ID为0,表示匿名用户或未登录用户。 然后函数直接返回,不再执行后续操作。 -
if ( is_object( $id ) && isset( $id->ID ) ) { $id = $id->ID; }
: 如果$id
是一个WP_User
对象,并且包含ID
属性,则提取出ID
属性的值。 这样做的目的是为了兼容传入WP_User
对象的情况,直接使用对象的 ID。 -
if ( ! ( $current_user instanceof WP_User ) ) { $current_user = new WP_User(); }
: 检查$current_user
是否是WP_User
的实例。如果不是,就创建一个新的WP_User
对象。 这通常发生在第一次调用wp_set_current_user()
的时候,$current_user
还没有被初始化。 -
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
属性。 -
$current_user = get_userdata( $id );
: 这是最核心的一步。使用get_userdata()
函数根据$id
从数据库中获取用户数据,并赋值给$current_user
。get_userdata()
函数会返回一个WP_User
对象,包含了用户的各种信息,如用户名、邮箱、角色等等。 -
if ( ! $current_user ) { $current_user = new WP_User( 0 ); return; }
: 如果get_userdata()
没有找到对应的用户(例如,ID不存在),则创建一个匿名用户。 这是一种安全措施,防止出现未知的用户状态。 -
wp_cache_set( 'current_user', $current_user, 'users' );
: 将当前用户对象缓存起来,方便下次使用。wp_cache_set()
函数是WordPress的缓存机制,可以提高性能。 -
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 '<br>你的邮箱是:' . $current_user->user_email;
if ( in_array( 'administrator', $current_user->roles ) ) {
echo '<br>你是管理员!';
}
} 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的底层机制。
八、思考题
- 如果我直接修改
$current_user
全局变量,而不是使用wp_set_current_user()
函数,会有什么潜在问题? set_current_user
动作钩子有哪些常见的应用场景?- 如果我想在用户登录后,立即更新用户的一些自定义信息(例如,上次登录时间),应该如何实现?
今天的讲座就到这里,谢谢大家! 希望大家继续深入研究WordPress源码,成为真正的WordPress专家!