各位观众老爷们,晚上好!我是你们的老朋友,今天咱们来聊聊WordPress源码里一个非常重要的文件——wp-includes/class-wp-user.php
。这个文件里藏着WordPress用户对象的秘密,以及权限验证的底层逻辑。别看它名字平平无奇,但它却是你理解WordPress用户管理和权限控制的关键钥匙。
咱们今天就用“扒皮抽筋”的方式,把这个文件给它彻底解剖一下,保证让你看完之后,对WordPress的用户系统有个更深的认识。
一、开场白:WP_User
类的前世今生
在WordPress的世界里,每一个用户都代表着一个WP_User
类的实例。这个类封装了用户的各种信息,比如用户名、密码、邮箱、角色等等。它就像一个“用户数据包”,里面塞满了关于这个用户的各种属性。
WP_User
类主要负责以下几个任务:
- 获取和设置用户信息: 从数据库中读取用户的各种信息,并允许你修改这些信息。
- 权限验证: 判断用户是否具有执行特定操作的权限。
- 角色管理: 管理用户的角色,并根据角色赋予相应的权限。
二、WP_User
类的核心属性和方法
要了解WP_User
类,首先要熟悉它的核心属性和方法。
2.1 核心属性
属性名 | 数据类型 | 描述 |
---|---|---|
$data |
array | 存储用户数据的关联数组。比如 $data['user_login'] 存储用户名,$data['user_email'] 存储邮箱。 |
$ID |
int | 用户ID。 |
$caps |
array | 用户拥有的所有权限的数组。这个数组是通过用户的角色和单独赋予的权限计算出来的。 |
$roles |
array | 用户拥有的角色数组。 |
$allcaps |
array | 用户所有可能的权限。这个属性很少直接使用。 |
$filter |
string | 用于过滤用户数据的过滤器名称。默认是 ‘raw’,表示未经任何处理的原始数据。 |
2.2 核心方法
方法名 | 描述 |
---|---|
__construct( $id = 0, $name = '', $site_id = '' ) |
构造函数。用于创建一个WP_User 对象。可以传入用户ID,用户名,站点ID等参数。 |
get( $key, $filter = 'raw' ) |
获取用户数据。$key 是要获取的数据的键名,$filter 是过滤器名称。例如,$user->get( 'user_login' ) 可以获取用户名。 |
has_cap( $cap ) |
判断用户是否具有某个权限。$cap 是要判断的权限名称。例如,$user->has_cap( 'edit_posts' ) 可以判断用户是否具有编辑文章的权限。 |
add_role( $role ) |
给用户添加一个角色。$role 是要添加的角色名称。 |
remove_role( $role ) |
移除用户的某个角色。$role 是要移除的角色名称。 |
set_role( $role ) |
设置用户的角色。注意,这个方法会移除用户的所有现有角色,然后添加新的角色。$role 是要设置的角色名称。 |
get_role_caps() |
获取用户所有角色的权限。 |
update_user_level_from_caps() |
根据用户的权限更新用户等级(user_level)。这个等级在WordPress 2.x时代使用,现在已经基本被角色和权限系统取代。 |
三、WP_User
类的构造函数:__construct()
WP_User
类的构造函数是创建用户对象的第一步。它的主要作用是从数据库中读取用户的各种信息,并初始化对象的属性。
public function __construct( $id = 0, $name = '', $site_id = '' ) {
if ( ! empty( $id ) ) {
$this->init( $id, $name, $site_id );
}
}
这个构造函数接受三个参数:
$id
: 用户ID。$name
: 用户名。$site_id
: 站点ID(用于多站点环境)。
如果传入了用户ID,构造函数会调用init()
方法来初始化用户对象。
四、init()
方法:初始化用户对象
init()
方法是WP_User
类中非常重要的一个方法。它负责从数据库中读取用户的各种信息,并设置对象的属性。
protected function init( $id, $name = '', $site_id = '' ) {
global $wpdb, $wp_roles;
$id = (int) $id;
if ( ! empty( $id ) ) {
$data = get_userdata( $id );
if ( false === $data ) {
$this->data = new stdClass();
$this->ID = 0;
return;
}
} elseif ( ! empty( $name ) ) {
$data = get_user_by( 'login', $name );
if ( false === $data ) {
$this->data = new stdClass();
$this->ID = 0;
return;
}
} else {
$this->data = new stdClass();
$this->ID = 0;
return;
}
$this->data = $data->data;
$this->ID = (int) $data->ID;
$this->caps = apply_filters( 'user_caps', $this->get_caps_from_db(), $this );
$this->roles = (array) get_user_meta( $this->ID, $wpdb->prefix . 'capabilities', true );
$this->allcaps = apply_filters( 'user_has_cap', $wp_roles->get_role_caps( $this->roles ), $this->caps, $this->name );
$this->filter = 'edit';
$this->update_user_level_from_caps();
}
这个方法做了以下几件事:
- 获取用户数据: 根据用户ID或用户名,从数据库中获取用户数据。这里使用了
get_userdata()
和get_user_by()
函数。 - 设置对象属性: 将获取到的用户数据设置到对象的
$data
、$ID
、$caps
、$roles
和$allcaps
属性中。 - 获取用户权限: 调用
get_caps_from_db()
方法从数据库中获取用户的权限,并使用apply_filters()
函数对权限进行过滤。 - 获取用户角色: 从用户元数据中获取用户的角色。
- 更新用户等级: 调用
update_user_level_from_caps()
方法更新用户等级。
五、get_caps_from_db()
方法:从数据库中获取用户权限
get_caps_from_db()
方法负责从数据库中获取用户的权限。它主要通过查询wp_usermeta
表,获取用户角色对应的权限。
protected function get_caps_from_db() {
global $wpdb;
$caps = get_user_meta( $this->ID, $wpdb->prefix . 'capabilities', true );
if ( ! is_array( $caps ) ) {
return array();
}
return $caps;
}
这个方法很简单,就是从wp_usermeta
表中读取wp_capabilities
这个元数据,这个元数据存储了用户角色的信息。
六、has_cap()
方法:权限验证的核心
has_cap()
方法是WP_User
类中最重要的方法之一。它负责判断用户是否具有某个权限。
public function has_cap( $cap ) {
global $wp_roles;
$args = array_slice( func_get_args(), 1 );
$args = array_merge( array( $cap, $this->ID ), $args );
$caps = apply_filters( 'user_has_cap', $this->allcaps, $args, $this );
if ( ! empty( $caps[ $cap ] ) ) {
return apply_filters( 'user_has_cap_default', $caps[ $cap ], $cap, $this->ID, $args );
} else {
return apply_filters( 'user_has_cap_default', false, $cap, $this->ID, $args );
}
}
这个方法的工作流程如下:
- 获取参数: 获取传递给
has_cap()
方法的参数。 - 应用过滤器: 使用
apply_filters()
函数对用户的权限进行过滤。user_has_cap
过滤器允许插件和主题修改用户的权限。 - 判断权限: 判断用户的权限数组中是否包含要判断的权限。
- 返回结果: 如果用户具有该权限,返回
true
,否则返回false
。
举个例子:
假设我们要判断用户是否具有编辑文章的权限:
$user = wp_get_current_user();
if ( $user->has_cap( 'edit_posts' ) ) {
echo '用户具有编辑文章的权限';
} else {
echo '用户不具有编辑文章的权限';
}
七、角色管理方法:add_role()
、remove_role()
和set_role()
WP_User
类还提供了一些方法来管理用户的角色:
add_role( $role )
: 给用户添加一个角色。remove_role( $role )
: 移除用户的某个角色。set_role( $role )
: 设置用户的角色。
public function add_role( $role ) {
if ( empty( $role ) ) {
return;
}
if ( ! in_array( $role, $this->roles ) ) {
$this->roles[] = $role;
$this->roles = array_unique( $this->roles );
$this->update_caps();
}
}
public function remove_role( $role ) {
if ( empty( $role ) ) {
return;
}
$key = array_search( $role, $this->roles );
if ( false !== $key ) {
unset( $this->roles[ $key ] );
$this->update_caps();
}
}
public function set_role( $role ) {
if ( empty( $role ) ) {
$this->roles = array();
} else {
$this->roles = array( $role );
}
$this->update_caps();
}
这三个方法都会调用update_caps()
方法来更新用户的权限。
八、update_caps()
方法:更新用户权限
update_caps()
方法负责更新用户的权限。它会重新计算用户的权限,并将权限保存到数据库中。
protected function update_caps() {
global $wpdb, $wp_roles;
$this->caps = apply_filters( 'user_caps', $this->get_caps_from_db(), $this );
$this->allcaps = apply_filters( 'user_has_cap', $wp_roles->get_role_caps( $this->roles ), $this->caps, $this->name );
update_user_meta( $this->ID, $wpdb->prefix . 'capabilities', $this->roles );
}
这个方法做了以下几件事:
- 获取用户权限: 调用
get_caps_from_db()
方法从数据库中获取用户的权限。 - 获取用户角色权限: 调用
$wp_roles->get_role_caps()
方法获取用户角色对应的权限。 - 合并权限: 将用户的权限和角色权限合并。
- 保存权限: 将用户的角色信息保存到
wp_usermeta
表中。
九、get()
方法:获取用户数据
get()
方法用于获取用户数据。它可以获取用户对象的任何属性。
public function get( $key, $filter = 'raw' ) {
if ( 'ID' === $key ) {
return $this->ID;
}
if ( isset( $this->data->$key ) ) {
$value = $this->data->$key;
} else {
return null;
}
if ( 'raw' === $filter ) {
return $value;
}
return sanitize_user_field( $key, $value, $this->ID, $filter );
}
这个方法接受两个参数:
$key
: 要获取的数据的键名。$filter
: 过滤器名称。
举个例子:
$user = wp_get_current_user();
$username = $user->get( 'user_login' ); // 获取用户名
$email = $user->get( 'user_email' ); // 获取邮箱
十、总结:WP_User
类的价值和意义
WP_User
类是WordPress用户系统的核心。它封装了用户的各种信息,并提供了权限验证和角色管理的功能。理解WP_User
类对于理解WordPress的用户管理和权限控制至关重要。
通过今天的“扒皮抽筋”,相信你已经对WP_User
类有了更深入的认识。下次再遇到用户权限相关的问题,你就可以胸有成竹,轻松应对了。
十一、思考题
WP_User
类是如何与WordPress的角色和权限系统协同工作的?- 如何使用
user_has_cap
过滤器来修改用户的权限? WP_User
类在多站点环境中有什么特殊之处?
希望大家多多思考,多多实践,才能真正掌握WordPress的精髓。
今天的分享就到这里,感谢大家的观看!咱们下次再见!