php位運算的許可權設計
阿新 • • 發佈:2018-12-07
一、優缺點
位運算的運算物件是二進位制位,速度快,效率高,而且節省空間,位運算做許可權控制也相當的靈活。但是位運算有很大的侷限,位移不能超過32次,這就要求許可權的數量不超過32中。
二、如何定義許可權
將許可權按照2的N次方來定義值,一次類推。為什麼要這個樣子定義,這個樣紙的定義是為了保證每個許可權值(二進位制)中只有一個1,而它恰好對應一種許可權。比如:
define('ADD',1); define('UPD',2); define('SEL',4); define('DEL',8); //給予某種許可權用到“位”運算 $a_access = ADD | UPD | SEL | DEL; // 擁有增刪改查許可權 $b_access = ADD | UPD | SEL; $c_access = ADD | UPD; $d_access = $c_access & ~UPD; // d 只擁有add //檢測是否擁有某種許可權用到 位與 運算子 var_dump($b_access & ADD); //1代表擁有 add var_dump($b_access & DEL); // 0 代表不擁有 del
三 、程式碼
/** * 簡單許可權類 */ class Peak_Auth { /** * 許可權計數器 * 作用在於生成許可權值 * @var integer */ protected static $authCount = 0; /** * 許可權名稱 * @var string */ protected $authName; /** * 許可權詳細資訊 * @var string */ protected $authMessage; /** * 許可權值 * @var int 2的n次方 */ protected $authValue; /** * 建構函式 * @param string $authName 許可權名稱 * @param string $authMessage 許可權詳細資訊 */ public function __construct($authName,$authMessage = ''){ $this->authName = $authName; $this->authMessage = $authMessage; $this->authValue = 1 << self::$authCount; self::$authCount++; } /** * 本類不允許物件複製的操作 * */ public function __clone(){ } /** * 設定許可權的詳細資訊 * @param string $authMessage */ public function setAuthMessage($authMessage){ $this->authMessage = $authMessage; } /** * 獲取權名稱 * @return int */ public function getAuthName(){ return $this->authName; } /** * 獲取許可權值 * @return int */ public function getAuthValue(){ return $this->authValue; } /** * 獲取許可權的詳細資訊 * @return string */ public function getAuthMessage(){ return $this->authMessage; } } /** * 簡單角色類 */ class Peak_Role { /** * 角色名 * @var string */ protected $roleName; /** * 角色擁有的許可權值 * @var int */ protected $roleValue; /** * 父角色物件 * @var Peak_Role */ protected $parentRole; /** * 建構函式 * @param string $roleName 角色名 * @param Peak_Role|null $parentRole 父角色物件 */ function __construct($roleName,Peak_Role $parentRole = null) { $this->roleName = $roleName; $this->authValue = 0; if($parentRole){ $this->parentRole = $parentRole; $this->authValue = $parentRole->getAuthValue(); } } /** * 獲取父角色的許可權 */ protected function fetchParentAuthValue(){ if($this->parentRole){ $this->authValue |= $this->parentRole->getAuthValue(); } } /** * 給予某種許可權 * @param Peak_Auth $auth $auth * @return 以便鏈式操作 */ public function allow(Peak_Auth $auth){ $this->fetchParentAuthValue(); $this->authValue |= $auth->getAuthValue(); return $this; } /** * 阻止某種許可權 * * @param Peak_Auth $auth * @return Peak_Role 以便鏈式操作 */ public function deny(Peak_Auth $auth) { $this->fetchParentAuthValue(); $this->authValue &= ~$auth->getAuthValue(); return $this; } /** * 檢測是否擁有某種許可權 * * @param Peak_Auth $auth * @return boolean */ public function checkAuth(Peak_Auth $auth) { return $this->authValue & $auth->getAuthValue(); } /** * 獲取角色的許可權值 * * @return int */ public function getAuthValue() { return $this->authValue; } }
四、呼叫測試
// 建立三個許可權: 可讀 可寫 可執行 $read = new Peak_Auth('CanRead'); $write = new Peak_Auth('CanWrite'); $exe = new Peak_Auth('CanExe'); // 建立一個角色 User $user = new Peak_Role('User'); // 建立另一個角色 Admin ,他擁有User 的所有許可權 $admin = new Peak_Role('Admin',$user); // 給予User 可讀,可寫的許可權 $user->allow($read)->allow($write); // 給予 Admin 可執行的許可權,另外還擁有User 的許可權 $admin->allow($exe); // 禁止Admin 的可寫許可權 $admin->deny($write); // 檢測 Admin 是否具有 某種許可權 var_dump($admin->checkAuth($read)); var_dump($admin->checkAuth($write)); var_dump($admin->checkAuth($exe));
參考地址 https://blog.csdn.net/jiangjundriver/article/details/73822896