用户
 找回密码
 入住 CI 中国社区
搜索
查看: 3074|回复: 3
收起左侧

[Others] 位运算比对来判断用户状态怎么理解?

[复制链接]
发表于 2014-12-2 16:06:55 | 显示全部楼层 |阅读模式
本帖最后由 ^淡如清风 于 2014-12-2 16:16 编辑

phpwind9.0中
有个方法如下:

PHP复制代码
class Pw {
/**
     * 位运算比对
     *
     * @param int $status 状态码
     * @param int $b 比对位置
     * @param int $len 比对位数
     * @return int
     */

    public static function getstatus($status, $b, $len = 1) {
        return $status >> --$b & (1 << $len) - 1;
    }
}
复制代码


然后【用户操作数据接口】中:
PHP复制代码
class PwUser {
   
    const FETCH_MAIN = 1; //获取用户基本信息,比如帐号、邮箱
    const FETCH_DATA = 2; //获取用户数据,比如积分、发帖数等论坛统计信息
    const FETCH_INFO = 4; //获取用户基本资料
    const FETCH_ALL = 7;
 
    const STATUS_UNCHECK = 1;//未验证用户
    const STATUS_UNACTIVE = 2;//未激活用户
    const STATUS_BAN_AVATAR = 3;//用户被禁止头像
    const STATUS_BAN_SIGN = 4;//用户被禁止签名
   
    const STATUS_ALLOW_LOGIN_ADMIN = 5;//该用户是否后后台权限
    const STATUS_SIGN_USEUBB = 6;//该用户签名是否使用UBB
}
 
复制代码


控制器中:
//如果已经激活
PHP复制代码
 
$status = $user['status']; //用户状态字段
if (!Pw::getstatus($status, PwUser::STATUS_UNACTIVE)) {
    //已经激活
}
复制代码


这个如何理解呢?也就是说getstatus()这个方法如何应用?困扰很久了。

@Hex
发表于 2015-3-30 17:32:48 | 显示全部楼层
顶,看不懂,那个了解的解释下。
发表于 2015-3-31 16:52:09 | 显示全部楼层
PHP复制代码
const STATUS_UNCHECK = 1;//未验证用户
    const STATUS_UNACTIVE = 2;//未激活用户
    const STATUS_BAN_AVATAR = 3;//用户被禁止头像
    const STATUS_BAN_SIGN = 4;//用户被禁止签名
   
    const STATUS_ALLOW_LOGIN_ADMIN = 5;//该用户是否后后台权限
    const STATUS_SIGN_USEUBB = 6;//该用户签名是否使用UBB
复制代码


这段代码规定了每个位置表示的意义,0表示是,1表示否,
如果某个$user['status']的值为 001110,【!这里是从右到左排列,跟十进制的排位一样】 表示该用户未激活,被禁止使用头像和签名,具体十进制值为  2^3 + 2^2  + 2= 14, 数据库中存的就是14。

接下来判断,该用户是否是 STATUS_UNACTIVE 状态, 使用方法:
PHP复制代码
public static function getstatus($status, $b, $len = 1) {
        return $status >> --$b & (1 << $len) - 1;
    }
复制代码

PHP复制代码
Pw::getstatus($status, PwUser::STATUS_UNACTIVE)
复制代码


该方法带入14这个十进制值, 也就是 001110, PwUser::STATUS_UNACTIVE的值为 2, 表示第二位指示该值的布尔值。

先将 001110右移动一位,变成 000111, 后面的 (1<< $len) -1 产生一个 11111这样的二进制, 然后做与运算, 都等于1的位则为true, 这里len默认为1, 则(1<< $len) -1 产生一个 1 这样的二进制, 记为000001,   000111 &000001 == 000001 == TRUE, 故得到 该用户没激活的信息。

如果$len 为2, 则产生一个000011的值, 则会同时检查到两位, 在这里将是未激活和禁止头像, 一次类推。

大约就是这样。~~

发表于 2015-4-12 18:46:41 | 显示全部楼层
这样设计有什么优势呢?

本版积分规则