二进制位运算和状态存储
在很多系统的权限/选项设置中 很多都用到了位运算的方法来存储多种标志位。在系统设计中只要是状态只有两种状态(0,1)的都可以用二进制位来表示,如果有多个状态用多个位或者还是新加字段吧。
(1)可以节省字段。一个字段只需要一个数字 就可以标识很多种设置和信息。
(2)可以处理位置状态需求,而无需更改数据表结构,比如需求增加是否绑定微信。
案例:User用户表stat字段
-
#二进制-标志位 0000 0000 0000 0001 第一位是否删除 0000 0000 0000 0010 第二位手机认证 0000 0000 0000 0100 第三位微信认证
-
2. 如何用一个数字来标识这些权限位呢
以刚才的user表中stat字段为例,假如通过select stat from user where name='yubing'; 检索出来的状态值为$stat =5,
如何检查是否微信认证呢? 看上面的对照表第三位1表示微信认证。
$stat=5;原来的状态值
$b=0b100;//第三位二进制值
$stat&$b = 5 & 0100 = 0b100 = 4 两个值相等表示状态为1,表示认证过了。
因此 检查,某个数代表的第N个权限标志位有没有置位(是1) 。同理检查是否手机认证,手机状态位为第二位
$stat&0b10==0b10 结果为0,表示没有手机认证。
/** $stat 状态值* $position 对应的第几位标志位* return 返回标志位是否为1*/ function getStat($stat,$position){$t = pow(2, $position - 1);return ((int)$stat&$t)==$t;}/** $stat 状态值* $position 对应的标志值* $val 设置标志位值1或者0* return 状态值*/ function setStat($stat,$position=1,$val=1){$t = pow(2, $position - 1);return $val==1? ((int)$stat | $t) : ((int)$stat & ~$t);}4.如何直接修改数据库中的标志位值呢?
比如修改用户的手机认证状态为认证 ,update user set stat=stat|2 where user='yubing'; 修改用户的微信状态为不认证 update user set stat=stat&(~4) where user='yubing'; 同时修改状态为手机认证,微信不认证 update user set stat=stat|2&(~4) where user='yubing';
5.使用二进制位的不便之处就是需要记忆各个位表示什么状态,程序的可读性比较差。折中的解决办法,直接设置一个数组变量$stat=['del'=>1,'mobile'=>0b10,'wx'=>4]; 值为运算后的的2进制或者10进制值
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
