浅析关于PHP位运算的简单权限设计


Posted in PHP onJune 30, 2013

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.实现简单的权限类和角色类
运用上面的权限操作方法,可以简单地封装成一个权限类和一个角色类。
/**
 * 简单权限类
 */
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 相关文章推荐
PHP 类相关函数的使用详解
May 10 PHP
解析posix与perl标准的正则表达式区别
Jun 17 PHP
解析:php调用MsSQL存储过程使用内置RETVAL获取过程中的return值
Jul 03 PHP
ThinkPHP关于session的操作方法汇总
Jul 18 PHP
PHP合并静态文件详解
Nov 14 PHP
PHP验证信用卡卡号是否正确函数
May 27 PHP
PHP微信红包API接口
Dec 05 PHP
非集成环境的php运行环境(Apache配置、Mysql)搭建安装图文教程
Apr 12 PHP
浅谈PHP Cookie处理函数
Jun 10 PHP
php+ajax+json 详解及实例代码
Dec 12 PHP
ThinkPHP使用getlist方法实现数据搜索功能示例
May 08 PHP
thinkphp5实现微信扫码支付
Dec 23 PHP
PHP删除HTMl标签的三种解决方法
Jun 30 #PHP
PHP删除HTMl标签的实现代码
Jun 30 #PHP
浅析php面向对象public private protected 访问修饰符
Jun 30 #PHP
解析link_mysql的php版
Jun 30 #PHP
分享8个最佳的代码片段在线测试网站
Jun 29 #PHP
php 验证码(倾斜,正弦干扰线,黏贴,旋转)
Jun 29 #PHP
浅谈web上存漏洞及原理分析、防范方法(文件名检测漏洞)
Jun 29 #PHP
You might like
DC四月将推出百页特刊漫画 纪念小丑诞生80周年
2020/04/09 欧美动漫
php array_slice函数的使用以及参数详解
2008/08/30 PHP
将一维或多维的数组连接成一个字符串的php代码
2010/08/08 PHP
如何让搜索引擎抓取AJAX内容解决方案
2014/08/25 PHP
Javascript 面向对象(一)(共有方法,私有方法,特权方法)
2012/05/23 Javascript
JS动态添加option和删除option(附实例代码)
2013/04/01 Javascript
javascript判断机器是否联网的2种方法
2013/08/09 Javascript
jsPDF导出pdf示例
2014/05/02 Javascript
JSONP跨域GET请求解决Ajax跨域访问问题
2014/12/31 Javascript
深入探讨JavaScript String对象
2015/03/09 Javascript
javascript产生随机数方法汇总
2016/01/25 Javascript
jQuery隐藏和显示效果实现
2016/04/06 Javascript
JavaScript中实现无缝滚动、分享到侧边栏实例代码
2016/04/06 Javascript
vue.js 表格分页ajax 异步加载数据
2016/10/18 Javascript
JS+Canvas实现的俄罗斯方块游戏完整实例
2016/12/12 Javascript
微信小程序实现action-sheet弹出底部菜单功能【附源码下载】
2017/12/09 Javascript
基于JS实现带动画效果的流程进度条
2018/06/01 Javascript
python自动化工具日志查询分析脚本代码实现
2013/11/26 Python
python通过elixir包操作mysql数据库实例代码
2018/01/31 Python
python爬虫爬取幽默笑话网站
2019/10/24 Python
tensorflow 2.0模式下训练的模型转成 tf1.x 版本的pb模型实例
2020/06/22 Python
Python request post上传文件常见要点
2020/11/20 Python
如何用PyPy让你的Python代码运行得更快
2020/12/02 Python
CSS3实现酷炫的3D旋转透视效果
2019/11/21 HTML / CSS
.NET程序员的几道面试题
2012/06/01 面试题
城市轨道专业个人求职信范文
2013/09/23 职场文书
优秀的计算机专业求职信范文
2013/12/27 职场文书
创业计划实施的7大步骤
2014/02/05 职场文书
电子商务专业求职信
2014/07/10 职场文书
争先创优公开承诺书
2014/08/30 职场文书
信用卡结清证明怎么写
2014/09/13 职场文书
买卖合同协议书范本
2014/10/18 职场文书
民政局离婚协议书范本
2014/10/20 职场文书
如何写一份成功的商业计划书
2019/06/25 职场文书
假期读书倡议书3篇
2019/08/19 职场文书
Python turtle编写简单的球类小游戏
2022/03/31 Python