Я пытаюсь выяснить, как ограничить доступ к определенным ресурсам в проекте 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());
}
И в моем контроллере (потому что я слышал , это то место, где вы должны поставить свой контроль доступа) У меня было бы что-то вроде этого:
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.