浅析关于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的面向对象编程
Oct 09 PHP
PHP+AJAX实现无刷新注册(带用户名实时检测)
Jan 02 PHP
解析如何屏蔽php中的phpinfo()函数
Jun 06 PHP
php include和require的区别深入解析
Jun 17 PHP
PHP文件读取功能的应用实例
May 08 PHP
php类的扩展和继承用法实例
Jun 20 PHP
Apache启动报错No space left on device: AH00023该怎么解决
Oct 16 PHP
深入理解PHP 数组之count 函数
Jun 13 PHP
Laravel等框架模型关联的可用性浅析
Dec 15 PHP
Laravel5.1 框架Request请求操作常见用法实例分析
Jan 04 PHP
laravel框架实现敏感词汇过滤功能示例
Feb 15 PHP
PHP 命名空间和自动加载原理与用法实例分析
Apr 29 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
利用PHP实现与ASP Banner组件相似的类
2006/10/09 PHP
发款php蜘蛛统计插件只要有mysql就可用
2010/10/12 PHP
js 无提示关闭浏览器页面的代码
2010/03/09 Javascript
js中获取 table节点各tr及td的内容简单实例
2016/10/14 Javascript
解决IE7中使用jQuery动态操作name问题
2017/08/28 jQuery
微信小程序实现默认第一个选中变色效果
2018/07/17 Javascript
微信小程序实现简单跑马灯效果
2020/05/26 Javascript
基于vue如何发布一个npm包的方法步骤
2019/05/15 Javascript
[06:43]2018DOTA2国际邀请赛寻真——VGJ.Thunder
2018/08/11 DOTA
利用Python演示数型数据结构的教程
2015/04/03 Python
简单介绍Python中的struct模块
2015/04/28 Python
Python导出DBF文件到Excel的方法
2015/07/25 Python
python Pygame的具体使用讲解
2017/11/03 Python
儿童编程python入门
2018/05/08 Python
Python读写zip压缩文件的方法
2018/08/29 Python
基于python实现学生管理系统
2018/10/17 Python
python 多线程重启方法
2019/02/18 Python
Python----数据预处理代码实例
2019/03/20 Python
python批量图片处理简单示例
2019/08/06 Python
Python socket聊天脚本代码实例
2020/01/02 Python
TensorFlow2.0:张量的合并与分割实例
2020/01/19 Python
解决pycharm编辑区显示yaml文件层级结构遇中文乱码问题
2020/04/27 Python
linux面试题参考答案(4)
2014/09/21 面试题
11月升旗仪式讲话稿
2014/02/15 职场文书
宣传部部长竞选演讲稿
2014/04/26 职场文书
企业安全生产演讲稿
2014/05/09 职场文书
环境卫生标语
2014/06/09 职场文书
党在我心中演讲稿
2014/09/02 职场文书
党员学习正风肃纪思想汇报
2014/09/12 职场文书
毕业实习计划书
2015/01/16 职场文书
2015年学生会纪检部工作总结
2015/03/31 职场文书
企业廉洁教育心得体会
2016/01/20 职场文书
导游词之无锡古运河
2019/11/14 职场文书
基于Redis过期事件实现订单超时取消
2021/05/08 Redis
Python中Cookies导出某站用户数据的方法
2021/05/17 Python
详细聊聊MySQL中慢SQL优化的方向
2021/08/30 MySQL