1. 写在最前面

    最近想写一个简单的关于权限处理的东西,之前我也了解过用二进制数的位运算可以出色地完成这个任务。关于二进制数 的位运算,常见的就是“或、与、非”这三种简单运算了,当然,我也查看了下PHP手册,还有“异或、左移、右移”这三个运算。记得上初中时数学老师就开始 唠叨个不停了,在此我也不想对此运算再作额外的说明,直接进入正题。

  2. 如何定义权限

    将权限按照2的N次方来定义值,依次类推。为什么要这样子定义呐?这样子定义保证了每个权限值(二进制)中只有一个1,而它恰好对应一种权限。比如:

    define('ADD', 1); // 增加权限
    define('UPD', 2); // 修改权限
    define('SEL', 4); // 查找权限
    define('DEL', 8); // 删除权限
  3. 权限操作

    权限操作其实涉及到“角色”这个概念。进行权限操作不外乎是让某个角色赋予某种权限、禁止某种权限和检测某个角色是否拥有某种权限。相对于这三个操作。可以用二进制数间的运算操作来很方便的实现。

    // 给予某种权限用到“位或”运算符
    $a_access = ADD | UPD | SEL | DEL; // a拥有增删改查权限
    $b_access = ADD | UPD | SEL; // b拥有增改查权限
    $c_access = ADD | UPD; // c拥有增改权限 // 禁止某种权限用“位与”和“位非”运算符
    $d_access = $c_access & ~UPD; // d只拥有了增权限 // 检测是否拥有某种权限用到“位与”运算符
    var_dump($b_access & ADD); // 1代表b拥有增权限
    var_dump($b_access & DEL); // 0代表b不拥有删权限
  4. 实现简单的权限类和角色类

    运用上面的权限操作方法,可以简单地封装成一个权限类和一个角色类。

    /**
    * 简单权限类
    * @author 27_Man
    */
    class Peak_Auth { /**
    * 权限类计数器
    * 作用在于生成权限值
    *
    * @var int
    */
    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++;
    } /**
    * 本类不允许对象复制操作
    */
    private function __clone() { } /**
    * 设置权限详细信息
    *
    * @param string $authMessage
    */
    public function setAuthMessage($authMessage) {
    $this->authMessage = $authMessage;
    } /**
    * 获取权限名称
    *
    * @return string
    */
    public function getAuthName() {
    return $this->authName;
    } /**
    * 获取权限值
    *
    * @return int
    */
    public function getAuthValue() {
    return $this->authValue;
    } /**
    * 获取权限详细信息
    *
    * @return string
    */
    public function getAuthMessage() {
    return $this->authMessage;
    }
    } /**
    * 简单角色类
    *
    * @author 27_Man
    */
    class Peak_Role { /**
    * 角色名
    *
    * @var string
    */
    protected $roleName; /**
    * 角色拥有的权限值
    *
    * @var int
    */
    protected $authValue; /**
    * 父角色对象
    *
    * @var Peak_Role
    */
    protected $parentRole; /**
    * 构造函数
    *
    * @param string $roleName 角色名
    * @param Peak_Role $parentRole 父角色对象
    */
    public function __construct($roleName, Peak_Role $parentRole = null) {
    $this->roleName = $roleName;
    $this->authValue = 0;
    if ($parentRole) {
    $this->parentRole = $parentRole;
    $this->authValue = $parentRole->getAuthValue();
    }
    } /**
    * 获取父角色的权限
    */
    protected function fetchParenAuthValue() {
    if ($this->parentRole) {
    $this->authValue |= $this->parentRole->getAuthValue();
    }
    } /**
    * 给予某种权限
    *
    * @param Peak_Auth $auth
    * @return Peak_Role 以便链式操作
    */
    public function allow(Peak_Auth $auth) {
    $this->fetchParenAuthValue();
    $this->authValue |= $auth->getAuthValue();
    return $this;
    } /**
    * 阻止某种权限
    *
    * @param Peak_Auth $auth
    * @return Peak_Role 以便链式操作
    */
    public function deny(Peak_Auth $auth) {
    $this->fetchParenAuthValue();
    $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;
    }
    }
  5. 对权限类和角色类的简单操作例子

    // 创建三个权限:可读、可写、可执行
    $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));

关于PHP位运算的简单权限设计的更多相关文章

  1. Java中的位运算及简单的算法应用介绍

    众所周知,计算机底层是二进制.而java作为一门计算机编程语言,也对二进制的位运算提供了完整的支持. 在java中,int是32位的,也就是说可以用来实现32位的位运算.方便起见,我们一般用16进制对 ...

  2. java位运算之简单了解

    1.十进制转化为二进制 将正整数转化为二进制的方法“除2取余,逆序排列”. 2.二进制转化为十进制 表示整数的二进制,第一位为标志位,0代表为正整数,位数从右开始,第一个位数为0,各位位数记作n,取各 ...

  3. C语言原码反码补码与位运算.

      目录:     一.机器数和真值     二.原码,反码和补码的基础概念     三.为什么要使用原码,反码和补码     四.原码,补码,反码再深入     五.数据溢出测试     六.位运算 ...

  4. 「C语言」原码反码补码与位运算

    尽管能查到各种文献,亲自归纳出自己的体系还是更能加深对该知识的理解.     本篇文章便是在结合百度百科有关原码.反码.补码和位运算的介绍并深度借鉴了张子秋和Liquor相关文章后整理而出.   目录 ...

  5. Java位运算总结:位运算用途广泛《转》

    前天几天研究了下JDK的Collection接口,本来准备接着研究Map接口,可是一查看HashMap类源码傻眼咯,到处是位运算实现,所以我觉得还是有必要先补补位运算知识,不然代码看起来有点费力.今天 ...

  6. C#中缓存的使用 ajax请求基于restFul的WebApi(post、get、delete、put) 让 .NET 更方便的导入导出 Excel .net core api +swagger(一个简单的入门demo 使用codefirst+mysql) C# 位运算详解 c# 交错数组 c# 数组协变 C# 添加Excel表单控件(Form Controls) C#串口通信程序

    C#中缓存的使用   缓存的概念及优缺点在这里就不多做介绍,主要介绍一下使用的方法. 1.在ASP.NET中页面缓存的使用方法简单,只需要在aspx页的顶部加上一句声明即可:  <%@ Outp ...

  7. C#枚举中的位运算权限分配浅谈

    常用的位运算主要有与(&), 或(|)和非(~), 比如: 1 & 0 = 0, 1 | 0 = 1, ~1 = 0 在设计权限时, 我们可以把权限管理操作转换为C#位运算来处理. 第 ...

  8. C#学习笔记-----C#枚举中的位运算权限分配

    一.基础知识 什么是位运算? 用二进制来计算,1&2:这就是位运算,其实它是将0001与0010做位预算   得到的结果是 0011,也就是3  2.位预算有多少种?(我们就将几种我们权限中会 ...

  9. C#枚举中的位运算权限分配

    什么是位运算 常用的位运算主要有与(&), 或(|)和非(~), 比如: & = ; | = ; ~ = ; 运用在权限设计中 先建立一个枚举表示所有的权限管理操作: [Flags] ...

随机推荐

  1. 【BZOJ-4653】区间 线段树 + 排序 + 离散化

    4653: [Noi2016]区间 Time Limit: 60 Sec  Memory Limit: 256 MBSubmit: 107  Solved: 70[Submit][Status][Di ...

  2. 【poj3122】 Pie

    http://poj.org/problem?id=3122 (题目链接) 题意 给出N个pie的半径和F个friend,每个friend得到的pie必须一样,求每个人能得到的pie的最大大小. so ...

  3. Linux-小命令技巧

    在bash中检查远程端口是否打开:echo >/dev/tcp/8.8.8.8./53 && echo "open"将进程挂起ctrl+z,不是万能的,有程序 ...

  4. Bzoj2118 墨墨的等式

    Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 1488  Solved: 578 Description 墨墨突然对等式很感兴趣,他正在研究a1x1+ ...

  5. RCE via XStream object deserialization && SECURITY-247 / CVE-2016-0792 XML reconstruction Object Code Inject

    catalogue . Java xStream . DynamicProxyConverter . java.beans.EventHandler . RCE via XStream object ...

  6. 主机宝(zhujibao) /a/apps/zhujibao/manager/apps/config/config.php no-password Login Vulnerabilities Based On Default cookie Verification From Default File

    catalog . 漏洞描述 . 漏洞触发条件 . 漏洞影响范围 . 漏洞代码分析 . 防御方法 . 攻防思考 1. 漏洞描述 主机宝管理程序使用了CodeIgniter框架,要想在CodeIgnit ...

  7. C++ 参考网站

    Reference Web cites for the C++ standard library cppreference cplusplus sgi IBM MSDN isocpp More res ...

  8. Ubuntu 之 Personal Package Archive (PPA)

    How do I use software from a PPA? To start installing and using software from a Personal Package Arc ...

  9. TypeScript Basic Types(基本类型)

    在学习TypeScript之前,我们需要先知道怎么才能让TypeScript写的东西正确的运行起来.有两种方式:使用Visual studio 和使用 NodeJs. 这里我选择的是NodeJs来编译 ...

  10. Deep Learning in NLP (一)词向量和语言模型

    原文转载:http://licstar.net/archives/328 Deep Learning 算法已经在图像和音频领域取得了惊人的成果,但是在 NLP 领域中尚未见到如此激动人心的结果.关于这 ...