用户
 找回密码
 入住 CI 中国社区
搜索
查看: 84189|回复: 108
收起左侧

[权限控制] 自制CI多权限控制类,轻松搞定多权限管理

    [复制链接]
发表于 2010-5-29 21:19:15 | 显示全部楼层 |阅读模式
本帖最后由 yunnysunny 于 2012-2-13 11:17 编辑

在处理OA系统时,我们不可避免的面临着众多的角色,而且令人头疼的是,我们还会面临一人身兼多职的情况,也就是说一个人拥有多个权限,所以一套完备的权限控制系统成为一个OA系统健壮性的首要条件。

那么怎样方便的给某个角色赋予多个权限,怎样判断某个角色是否含有某特定权限,又怎样来删除掉多个权限中的某个一个权限呢,等等问题需要解决。为了说明这些问题的解决思路,我们假设系统中一共拥有15个角色,分别为:普通用户、营员、外语选手、通讯录、软件选手、校方负责人、评审专家、指导老师、准命题老师、命题老师、就业服务人员、编辑、命题评审组长、大赛负责人、管理员、培训老师。我们用15位二进制来表现他们的权限值。权限的对应关系如下表:

位数

拥有权限

转化后的十进制数

14

培训老师

16384

13

管理员

8192

12

大赛负责人

4096

11

命题评审组长

2048

10

编辑

1024

9

就业服务人员

512

8

命题老师

256

7

准命题老师

128

6

指导老师

64

5

评审专家

32

4

校方负责人

16

3

软件选手

8

2

外语选手

4

1

营员

2

0

普通用户

1

-1或其他

非法用户

--

我们在处理时,用户的权限是一串15位二进制数字,每位代表一个权限,比如说一个用户同时具有外语选手、营员和普通用户的权限,那么他的二进制权限字符串就是:

0000000000001110,1,2位权限)

同样,如果一个用户同时具有大赛管理员和编辑的权限,那么他们的权限字符串就是:

00101000000000010,12位权限)

我们在数据库中存储的是二进制转化后生成的十进制,这样我们前面所说的第一个用户的权限值就是7(外语选手、营员和普通用户:4+2+1),第二个用户的权限值就是5120(大赛负责人、编辑:4096+1024)。

利用这个转化规则,一个用户可以有多个权限,当我们判断一个用户是否具有某个权限时,只要把他的权限值和特征权限值相与就可以了。比如说,我们还拿刚才举的第二个用户做例子,他的权限是5120,我们判断他是否是大赛负责人,只需将51204096相与,结果返回为真,说明它具有大赛负责人权限;如果要判断他是否是管理员,只需将51208192相与,结果为假,说明他不是管理员。


添加和删除权限也很简单,只需把对应权限为置1或者置零,例如添加2号位权限,只需将原权限或上0000000000000100,删除2号位权限只需将原权限与上111111111111011
level.zip (2.29 KB, 下载次数: 2414)
测试类.7z (825 Bytes, 下载次数: 1157)
使用该功能的项目应经开源,详见http://qloa.sf.net

评分

参与人数 3威望 +9 收起 理由
skip_to_my_lou + 3 赞一个!
lynn.wang + 1
Hex + 5 原创内容

查看全部评分

本帖被以下淘专辑推荐:

 楼主| 发表于 2014-8-30 10:21:16 | 显示全部楼层
magicone 发表于 2014-7-13 12:17
权限放session array里速度也不慢啊~~~ 为啥非要这么做

session里面的东西肯定放的越少越节省资源,你的设计要放一个数组,但我这里就放一个数字。
 楼主| 发表于 2010-8-1 10:31:53 | 显示全部楼层
回复 15# tacyuuhon

在构造函数中读取了一个config.php中的值level_nums,它的意思就是系统中角色的个数,如果是15中角色,就要配置config['level_nums']=15,这个会影响生成的二进制字符串的长度。假设在config.php中设置的level_nums为15,但是你要设置一个权限值为16的权限,将会产生一个类似“溢出”的结果,它将得到一个00000000000000,即产生的结果为0。
发表于 2010-5-30 10:43:06 | 显示全部楼层
不错,值得大家学习
发表于 2010-5-29 21:46:10 | 显示全部楼层
太需要这样的东西了!呵呵
发表于 2010-5-29 22:51:11 | 显示全部楼层
不错不错,下回来研究研究
发表于 2010-5-29 23:35:36 | 显示全部楼层
楼主,有个问题想请教一下:
函数 GetLevel 的返回值,你是这样子写的:
                if($j==1)   return $returnArray[0];
                return ($j>0)? $returnArray : -1;
返回值有可能是单个字符,也有可能是个数组,为什么不统一返回数组呢?请问您这样写的目的是?
发表于 2010-5-30 20:17:56 | 显示全部楼层
想法不错 我原来用array的形式来做的 效率比这个低多了。
 楼主| 发表于 2010-5-31 20:53:13 | 显示全部楼层
回复 4# lcnphp


   当初团队中人提的建议,现在想想,写的不是很合适,你可以修改成自己想要的。
发表于 2010-6-2 10:33:04 | 显示全部楼层
学习一下,一直想php oa权限流方面的东西。
发表于 2010-6-3 08:50:44 | 显示全部楼层
添加:
位数 拥有权限
16   SuperHero
删除:
位数 拥有权限
7     准命题老师

认证系统废啦。 扩展性不好。
 楼主| 发表于 2010-6-4 09:46:31 | 显示全部楼层
回复 9# tacyuuhon

不明白你的意思。好像是你没有用对代码。

本版积分规则