Php 如何管理ACL规则?
我正在编写一个ACL类,它的规则来自“setter”方法: 但是当它增长时,它看起来将是一场性能灾难,记住读取数组(推断Php 如何管理ACL规则?,php,design-patterns,acl,Php,Design Patterns,Acl,我正在编写一个ACL类,它的规则来自“setter”方法: 但是当它增长时,它看起来将是一场性能灾难,记住读取数组(推断是允许的(…)结果)和写入数组(规则冲突、覆盖、角色和资源之间的继承……)的逻辑 也许我从一开始就错了,那些“二传手”才是问题所在是否有任何完善的设计模式可以遵循?您可以避免通过延迟加载填充整个ACL列表 这是一个非常简单的方法,但概念应该扩展。这假设对于给定的请求,大多数(如果不是所有的话)acl检查将针对单个用户角色,但相同的技术可用于控制器或角色与控制器的组合 以表格的方
是允许的(…)
结果)和写入数组(规则冲突、覆盖、角色和资源之间的继承……)的逻辑
也许我从一开始就错了,那些“二传手”才是问题所在是否有任何完善的设计模式可以遵循?您可以避免通过延迟加载填充整个ACL列表 这是一个非常简单的方法,但概念应该扩展。这假设对于给定的请求,大多数(如果不是所有的话)acl检查将针对单个用户角色,但相同的技术可用于控制器或角色与控制器的组合 以表格的方式(csv、json、ini、db table或php include)定义acl,无论您能得到什么,都是一个包含允许或拒绝、操作和角色的数组。我将使用php include,因为它假设的是最小的。每个角色都有一个这样的角色
return array(
array("allow", "someController", "someAction"),
array("deny", "someController", "someOtherAction")
);
在AccessControlList中添加一个方法来读取和处理这样的文件
protected function readConfig($role, $source){
$dat = include($source);
foreach($dat as $rule){
switch($rule[0]){
case "allow": $this->allow($rule[2], $rule[3], $role); break;
case "deny": $this->deny($rule[2], $rule[3], $role); break;
}
}
}
添加将角色绑定到文件的方法。这将简单地添加到您现有的acl中
public function setRules($role, $source){
$this->acl[$role] = $source;
}
然后在isAllowed中检查角色的acl节点是字符串还是数组
public function isAllowed($role, $subject, $action){
if (is_string($this->acl[$role])){
$this->readConfig($role, $this->acl[$role]);
}
// do your acl check as normal.
}
通过延迟加载,可以避免填充整个ACL列表 这是一个非常简单的方法,但概念应该扩展。这假设对于给定的请求,大多数(如果不是所有的话)acl检查将针对单个用户角色,但相同的技术可用于控制器或角色与控制器的组合 以表格的方式(csv、json、ini、db table或php include)定义acl,无论您能得到什么,都是一个包含允许或拒绝、操作和角色的数组。我将使用php include,因为它假设的是最小的。每个角色都有一个这样的角色
return array(
array("allow", "someController", "someAction"),
array("deny", "someController", "someOtherAction")
);
在AccessControlList中添加一个方法来读取和处理这样的文件
protected function readConfig($role, $source){
$dat = include($source);
foreach($dat as $rule){
switch($rule[0]){
case "allow": $this->allow($rule[2], $rule[3], $role); break;
case "deny": $this->deny($rule[2], $rule[3], $role); break;
}
}
}
添加将角色绑定到文件的方法。这将简单地添加到您现有的acl中
public function setRules($role, $source){
$this->acl[$role] = $source;
}
然后在isAllowed中检查角色的acl节点是字符串还是数组
public function isAllowed($role, $subject, $action){
if (is_string($this->acl[$role])){
$this->readConfig($role, $this->acl[$role]);
}
// do your acl check as normal.
}
你看过zend_acl吗?可能会给你一些关于ACL规则的见解。@AlexP事实上我的实现是zend_ACL的最低版本(如果我真的了解它的工作原理的话)。问题是,我认为所有的简化都会为混乱的数组付出代价。@Orangepill,听起来不错,它能激发一个答案吗?你看过zend_acl吗?可能会给你一些关于ACL规则的见解。@AlexP事实上我的实现是zend_ACL的最低版本(如果我真的了解它的工作原理的话)。问题是,我认为所有的简化都将为混乱的数组付出代价。@Orangepill,听起来不错,它能激发一个答案吗?如果我理解,你的解决方案依赖于每个角色都有独立的文件。当然,这是一个选项,但您让我想到将规则存储在一个唯一的文件中,并在
readConfig
方法中过滤它们(按角色和资源),而不使用setRules
方法。现在我认为本质上是将规则集与ACL对象分离,这打开了许多从整个规则中选择范围的方法。这很适合我:)如果我理解的话,您的解决方案依赖于为每个角色提供独立的文件。当然,这是一个选项,但您让我想到将规则存储在一个唯一的文件中,并在readConfig
方法中过滤它们(按角色和资源),而不使用setRules
方法。现在我认为本质上是将规则集与ACL对象分离,这打开了许多从整个规则中选择范围的方法。适合我:)