discuz!1.5x论坛的会员组有多种形式,一般分为管理组和用户组,而用户组又可以分为多种。此次开发“VIP会员在线购买”插件,涉及到的一项就是需要修改用户的会员组,并可以设置一定的有效期。
经过简单分析,得知pre_common_member表里面有四个字段跟会员组相关,分别是adminid、groupid、groupexpiry和extgroupids。adminid是管理组的唯一标识符;groupid是用户组的标识符;extgroupids是扩展组的标识符,在后台的“用户管理”里面就可以看到相关设置的地方。这里单独说一下奇怪的地方,groupexpiry是账户过期时间,这个过期时间就是后台的“用户组过期时间”保存的字段,这个字段神奇就神奇在不管“主用户组”过期时间还是“扩展组用户”过期时间,都会修改这个字段。那么问题来了,那么“主用户组”和“扩展用户组”过期时间不一样怎么办?实际应用中这两个地方不同的可能性太大了,难道这是一个bug?这还真不是一个bug,下面再慢慢分析后就知道了。根据后台用户管理界面的设置,有两项是“过期后用户组变为”和“过期后管理组变为”的选项,因此还应该有一个用来保存用户过期后状体的字段,可是把pre_common_member表翻烂了也没有找到。于是就自己操刀慢慢顺着后台member的相关源代码分析,一个小时的奋战啊,终于找到了一个叫pre_common_member_field_forum的表,表名看起来是存放会员在论坛上相关应用设置的。里面的groupterms就是我们要找的字段了,里面存放的是序列化后的结果,我们只要unserialize()下就可以得到两个数字,这里就是我们要找的了。本想分析下源代码得出这个数组存放的格式,可是代码太多又不熟悉,笨人有笨办法,就是通过后台设置后对比这个字段的存放格式,然后根据规律猜测出数组的存放形式,下面就是分析过程。
首先设置了用户用户组(24)和管理组(2),然后设置过期时间为2011-5-28(即下面的1306512000),过期后用户组(10,10其实是后台“会员用户”的标识,就是根据积分多少自动变化的组)和管理组(2)。并设置了3个扩展用户组,过期时间为2020-5-28(1590508800)然后查看相关字段的结果:
首先是pre_common_member_field_forum的groupterms反序列化后print_r结果:
Array
(
[main] => Array
(
[time] => 1306512000
[adminid] => 2
[groupid] => 10
)
[ext] =>Array
(
[24] => 1306512000
[18] => 1590508800
[23] => 1590508800
[25] => 1590508800
)
)
其次pre_common_member的4个相关字段的结果:
adminid:2
groupid:24
groupexpiry:1306512000
extgroupids:18 23 25
简单的分析下就知道各字段的用途了,pre_common_member表是用来存放目前用户属于的所有用户组,过期时间也是所有设置的过期时间点里面最早发生的那个时间点。groupterms的数组里面,main里面存放的是过期之后的用户组状态,ext里面是目前的用户组状态,其中第一条是主用户状态,剩下的为扩展用户组状态。
这样就很明确了,pre_common_member表存放的是简化后的用户组信息,使系统可以快速获取对应用户的目前用户组状态。用户的完整用户组信息保存于pre_common_member_field_forum表。其实这样做也是discuz论坛优化的一个提现。使用空间换取时间,加快运行速度。