2011-02-17 100 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()) { 
    // 
}