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-1670】Building the Moat护城河的挖掘 Graham扫描法 + 凸包

    1670: [Usaco2006 Oct]Building the Moat护城河的挖掘 Time Limit: 3 Sec  Memory Limit: 64 MBSubmit: 464  Solv ...

  2. 基本概率分布Basic Concept of Probability Distributions 5: Hypergemometric Distribution

    PDF version PMF Suppose that a sample of size $n$ is to be chosen randomly (without replacement) fro ...

  3. Hackerrank Going to the Office

    传送门 Problem Statement Ms.Kox enjoys her job, but she does not like to waste extra time traveling to ...

  4. Error=Bias+Variance

    首先 Error = Bias + Variance Error反映的是整个模型的准确度,Bias反映的是模型在样本上的输出与真实值之间的误差,即模型本身的精准度,Variance反映的是模型每一次输 ...

  5. 【Alpha阶段】第五次Scrum例会

    由于软工整个项目规划延期1周,我们将停止2天的Scrum,进行相应的修整 会议信息 时间:2016.10.21 22:30 时长:20min 地点:大运村1号公寓5楼楼道 类型:日常Scrum会议 个 ...

  6. HTML5系列一(属性概述)

    HTML5概述 HTML5於2004年被WHATWG(网页超文本技术工作小组)提出,於2007年被W3C接纳 在2008年1月22日,第一份正式草案已公布.WHATWG表示该规范是目前正在进行的工作, ...

  7. 初识PHP

    初识PHP 虽然是做前端的,可是平时看书.做项目都会与后端PHP相关,但却不是很了解,并经常听PHP大神说:PHP是世界上最好的语言!因此,通过这篇博文学习.总结PHP,来认识认识这个“世界上最好的语 ...

  8. Hibernate_增删改

    package com.etc.test;import java.util.List;import org.hibernate.Session;import org.hibernate.Session ...

  9. ubuntu默认防火墙

    ubuntu 9.10默认的是UFW防火墙,已经支持界面操作了.在命令行运行ufw命令就可以看到提示的一系列可进行的操作. 最简单的一个操作:sudo ufw status可检查防火墙的状态,我的返回 ...

  10. 日志分析 第七章 安装grafana

    grafana依赖mysql存储数据,首先需要安装mysql 安装mysql 解压 # groupadd mysql # useradd -s /sbin/nologin -g mysql mysql ...