php 位运算与权限,PHP中的二进制位运算和权限存储

举例 dicuz的帖子表的status字段,官方预留了16个标志位(0×0000 – 0xFFFF) 即2^16

目前规划使用了只有8个标志位,如下

#数据库表字段结构

#type:smallint 大小两字节 8*2=16位

`status` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT '用户状态:采用二进制位一个标志位代表一种状态',

#二进制-标志位

0000 0000 0000 0001 是否缓存帖子位置信息

0000 0000 0000 0010 是否回帖只对管理人员和发帖者可见

0000 0000 0000 0100 是否抢楼贴

0000 0000 0000 1000 是否倒序查看回帖

0000 0000 0001 0000 是否存在主题图章标志位

0000 0000 0010 0000 回复是否通知作者

0000 0000 0100 0000 是否推送到QQ空间

0000 0000 1000 0000 是否推送到腾讯微博

这8种状态可以使用一个数字来同时表示,节省了字段

discuz对此的二进制位运算实现

/**

* 位运算-获取$status值得第$position位的值

*

* @param int $status

* @param int $position 标志位

* @return int 返回该标志位的值

*/

function getstatus($status, $position) {

$t = $status & pow(2, $position - 1) ? 1 : 0;

return $t;

}

/**

* 位运算-设置$position位的$value值,并返回新状态值

*

* @param int $position 标志位

* @param int $value 设置的标志位的值 0或1

* @param int $baseon 状态值

* @return int 返回新状态值

*/

function setstatus($position, $value, $baseon = null) {

$t = pow(2, $position - 1);

if($value) {

$t = $baseon | $t;

} elseif ($baseon !== null) {

$t = $baseon & ~$t;

} else {

$t = ~$t;

}

return $t & 0xFFFF;

}

#注意 写这段代码的人显然受到了C的影响 其实 $a & ~$b 和 $a ^ $b 是等效的 只不过 ^是PHP的写法 另外 pow(2, $position - 1)换成 1 << ($position -1) 其实更好理解。

如何用一个数字来标识这些权限位呢

以刚才discuz的帖子表达status字段为例,检查帖子回复是否通知作者 就看二进制上第六位是否是置位为1 那么怎么检查呢?就是用上面我们提到的与运算。

与运算是将把 $a 和 $b 中都为 1 的位设为 1。那么假设

$a=36=0b 0010 0100

$b=0b 0010 0000

$a&$b = 0b 0010 0100 & 0b 0010 0000 = 0b 0010 0000 = 32 = 26-1 = 25

因此 检查,某个数代表的第N个权限标志位有没有置位(是1) 只要选择该数与仅该标志位置位的操作数2N-1进行与运算即可,相反要计算某个标志位被置位的数字 只要选择合适的操作数进行或运算即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值