1. 程式人生 > >php位運算的許可權設計

php位運算的許可權設計

一、優缺點

位運算的運算物件是二進位制位,速度快,效率高,而且節省空間,位運算做許可權控制也相當的靈活。但是位運算有很大的侷限,位移不能超過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