【发布时间】:2012-02-10 09:27:28
【问题描述】:
我正在尝试弄清楚如何限制对我目前正在处理的 PHP 项目中特定资源的访问。我一直在寻找现有的解决方案,但没有一个真正符合我的需要(例如 Zend_Acl)。
现在我想出了这样的事情:(当然,这是非常、非常简化的。没有例外或其他任何情况。足以理解重点)
class Access {
protected $_context;
protected $_handlers;
public function __construct($context) {
$this->_context = $context;
}
public static function registerHandler(Access_Handler $handler) {
$key = $handler->getContextType().'/'.$handler->getResourceType();
self::$_handlers[$key] = $handler;
}
public function isAllowed($resource) {
return $this->getHandler($resource)->isAllowed($this->_context, $resource);
}
public function getHandler($resource) {
// Look for and return the appropriate handler for the combination of
// $context and $resource
}
}
abstract class Access_Handler {
$_contextType;
$_resourceType;
abstract public function isAllowed();
}
class Access_Handler_UserInvoice extends Access_Handler {
$_contextType = 'User';
$_resourceType = 'Invoice';
public function isAllowed($user, $invoice) {
if($invoice->user_id === $user->id) {
return true;
}
return false;
}
}
然后我会在我的应用程序引导中执行类似的操作:
protected function $_initAccessHandlers() {
Access::registerHandler(new Access_Handler_UserInvoice());
}
在我的控制器中(因为 I've heard 那是你应该放置访问控制的地方)我会有这样的东西:
class InvoiceController {
public function viewAction() {
// $this->me is of type User
$access = new Access($this->me);
if($access->isAllowed($this->invoice)) {
// ...
}
}
}
我没有测试过代码,所以可能有错别字或其他错误,但我想你明白了要点。此外,实际上我可能会将 Access 实现为 Singleton 或 Multiton,但这不是我的问题所在。
这是正确的做法吗?这对我来说似乎很自然,但我想知道为什么没有其他人以这种方式这样做。
我的开发栈是 PHP/MySQL/Zend Framework/Doctrine。
【问题讨论】:
-
您在这里尝试做的所有事情都已经在 Zend_Acl 中使用动态断言完成了,不是吗?
-
在我的情况下有点复杂。例如,我希望用户能够访问其同事(属于同一公司)的发票,但不能修改它们。 AFAIK,这对于 Zend_Acl 来说是非常困难的,如果不是不可能的话。 (我还没有研究 Zend_Acl_Assert_Interface ..这是我想要的吗?)
标签: php model-view-controller acl