2011-02-17 47 views
2

有些用户在系统中拥有不同的权限。他们的特权是分层的PHP OOP体系结构问题(面向角色的OOP)

class User{//abstract user not logged in 
    //function signIn(){} 
} 

class Guest extends User{ 

} 

class FullUser extends Guest{ 
    static function signUp(){}//create an account 
    function signOut(){} 
} 

class Moderator extends FullUser{ 
      function edit(){}//some new method introduced here,never introduced before 
} 

class Admin extends Moderator{ 
      //can do everything 
} 

//can use 
FullUser::signUP() 

我的建筑很好吗? 你能告诉我其他什么吗? 我想知道哪个是创建用户的最佳方式 - 写一个构造函数?或者让它成为“工厂”功能。

function signIn($username, $password) 

我是新在PHP中面向对象,所以我接受明智建议,链接等


编辑: 我打算用这个角色 - 检查系统:

if(!method_exists($user->addComment())) die('Access denied') 

您对此有何看法?


编辑2: 应该创建与Y轴作用,在X轴和方法的角色表?

  comment | post | editPost | kill 
guest   0  0  0   0 
fullUser  1  0  0   0 
moderator  1  1  1   0 
admin   1  1  1   1 

后来我应该写这样的事情

function addComment($user){ 
if(!$ROLES [$this->$role][__FUNCTION__])return; 
.... 
} 

那是优于OOP,聪明的程序员?

回答

4

角色绝对是要走的路。

您可以做一些简单的事情,比如让每个用户拥有public $role属性,其中$ role只是一个数字(例如9 = admin,6 = fulluser,3 = guest)。

数据库表是这样的

Users 
id username password role 
1 admin  somePass 9 
2 someUser somePass 3 

在代码中你不喜欢的东西`如果($用户>角色> = 9)“。

如果你愿意,你可以有一个角色表,而不是仅仅使用号码 - 这样的:

Roles 
id role 
1 admin 
2 fulluser 
3 user 
4 guest 

你也可以让它更先进的其中一个用户可以拥有角色数组。

+0

编辑2是否在我的文章中扩展了你的方法? – Dan 2011-02-18 00:26:19

+0

嗯,是的...... – 2011-02-18 00:33:19

3

我更倾向于根据基于角色的系统设置权限。它更灵活一点,就是用户可以与一个或多个角色相关联,并且根据这些角色他们可以执行不同的操作。

+0

请你介绍我的简单例子“基于角色的syslem”? – Dan 2011-02-18 14:09:26

2

通常,我倾向于使用按位权限系统,其中权限是根据个人需求设置的,并且可以通过组权限进行覆盖,例如,您可以查看用户是否具有权限,如果不是,请参阅如果他们所属的团体拥有它等等。这在添加新功能和可扩展性方面似乎非常灵活。

虽然你的方法会工作。就构造函数而言,我可能不会覆盖它,并让它登录用户,获取他们的统计信息和权限等,并确保在每个新页面上调用此函数。然后创建简单的函数,比如class :: listPermissions等,它们都使用parent :: function,比如parent :: listPermissions。这将有助于继承,例如在我的示例中,admin类的列表权限将调用Admin :: listPermissions,FullUser :: listPermissions,Guest :: listPermissions,以便它们获得它们继承的所有权限。

我一般没有很多基于类的系统的运气,但我已经看到他们在行动之前。

2

我认为你的继承层次有点搞砸了。从我可以看到它看起来像:

User // abstract 
    Guest // anonymous and can't do anything 
     FullUser // can sign up 
       Admin // can do everything 

换句话说,Guest s为用户,FullUser s为Guest S,Admin s为FullUser S和因此Admin s为也Guest秒。我想我可以看到你在做什么 - 逐渐地在继承层次下进一步提供更多的权限。然而,结果是你将在扩展类的具体类上有很高的耦合度,并且你将完全错过OOP最大的好处之一 - 多态性。

许多其他海报建议使用角色来代替,这很好。你也可以通过继承来完成它,其中User是一个抽象类,它定义了抽象方法signInsignOut,不同的子类如AdminUserGuestUser对这些方法实现完全不同的行为。对于Guest,没有signOut的行为。

+0

我会失去多态吗?假设我写了`$ moderator-> addComment()`addComment在`FullUser`类中定义了 – Dan 2011-02-18 00:08:08

+0

读你的第二段 - 这也是一个对象模型!它是多态的。什么是角色系统?这是基于数组吗?如arex1337建议? – Dan 2011-02-18 00:19:00

3

我也定义了一个基于角色的模式。

首先,让我们创建一个类用户凭据:

class CUserCredentials { 

    public 
     $orgID, 
     $ordSubID, 
     $password; 

    // or protected instance variables an accessors 

} // CUserCredentials 

在我们的情况下,用户标识一个组织ID [公司数量],相对于它的一些ORGID [例如他的员工号码]和密码。

的方法,检验对凭证一定的作用的被包封的由一个抽象类:

class CAbstractRoleVerifier { 

    // return 
    public static function hasRoleUsingUserCredentials(CUserCredentials $cred); 

} 

方法hasRoleUsingUserCredentials()验证凭证反对“任何”,例如一个数据库表。

然后我们定义一个抽象的角色管理器,这是一个具体的实施模板:

class CAbstractRoleManager { 

    static protected 
     $possibleRoles; 

    // The standard role 
    protected $primaryRole; 

    // The other roles he is able to use 
    protected $userrRoles; 

    // verifies all defined roles 
    public function verifyAllRoles(CUserCredentials $cred); 

} 

虽然上面类是我们的框架的一部分,我们的应用程序需要实现一个具体的角色管理器,如像这样:

class CMyRoleManager extends CAbstractRoleManager { 

    // these two are nomal roles 
    const ROLE_USER  = 1; 
    const ROLE_MANAGER = 2; 

    // this is a special role, which allows to 
    const ROLE_ADMIN = 3; 

    protected 
     $userRoles; 

    public function __construct() { 


     // prepare CMyRoleVerifierUser, CMyRoleVerifierManager as subclasses of the    
     // above class   
     self::$possibleRoles = array(
      self::ROLE_USER  => new CMyRoleVerifierUser(), 
      self::ROLE_USER  => new CMyRoleVerifierManager(), 
      self::ROLE_ADMIN => new CMyRoleVerifierAdmin(), 
      ); 

     // Initially, user has no role 
     $this->userRoles = array(); 

     $this->mainRole = FALSE; 


    } 

    public function verifyAllRoles(CUserCredentials $cred) { 

     foreach(self::$possibleRoles as $roleID => $verifier) { 

      if ($verifier->hasRoleUsingUserCredentials($cred)) { 

       $this->userRoles[ $roleID ] = $roleID; 
      } 

     } 

    } 

    public function hasRole($aRoleID) { 

     return isset($this->userRoles[ $roleID ]); 

    } 

} 

请注意,验证角色集的过程和验证特定角色的过程是如何在不同的类中分离的。

虽然人们可以使用类/子类设计,但我更喜欢这种设计。它允许保留一组可能具有任何关系的角色,不仅ROLE_MANAGER被允许对所有ROLE_USER 某些其他操作。

在我的情况下,ROLE_ADMIN是一个特殊的角色。如果用户针对ROLE_ADMIN进行验证,他会看到启用了某些管理功能。除了其他特殊行动外,他可以暂时表现得好像他的另一个角色。 $ this-> mainRole在这里没有完全实现

1

忽略数据库设计,你应该只有一个用户类,而不是拥有越来越强大的用户继承系统 - 这可以很容易地改变。有时候你可能想要一个不太强大的用户能够做一些更强大的用户不能做的事情。

让你的用户对象有一个或多个角色。然后做这样的事情:

if ($user->isAdmin()) { 
    // 
}