二進位制位運算和狀態儲存
阿新 • • 發佈:2018-11-13
在很多系統的許可權/選項設定中 很多都用到了位運算的方法來儲存多種標誌位。在系統設計中只要是狀態只有兩種狀態(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,表示沒有手機認證。
3.php對應的演算法
4.如何直接修改資料庫中的標誌位值呢? 比如修改使用者的手機認證狀態為認證 ,update user set stat=stat|2 where user='yubing';/* * $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); }
修改使用者的微信狀態為不認證 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進位制值