首頁 > 後端開發 > php教程 > php中實作簡單的ACL

php中實作簡單的ACL

高洛峰
發布: 2023-03-01 13:26:01
原創
1188 人瀏覽過

程式碼如下:
-- ACL 表
-- 表的結構`aclresources`
DROP TABLE IF EXISTS `aclresources`; 
如果不存在`aclresources`,則建立表(
`rsid` variid`rsid`
`access` int(4) NOT NULL default 0,
`desc` varchar(240) NOT NULL default '',
` create_at` int(10) 無符號NOT NULL 預設1,
`updated_` int(10)無符號NOT NULL 預設0,
主鍵(`rsid`) 
)DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 
-- 表的結構`aclroles`
DROP TABLE IF則建立表格(
`id` int(10) unsigned NOT NULL auto_increment,
`rolename` varchar(32) NOT NULL,
`desc` varchar(240) NOT NULL default '',
`desc` varchar(240) NOT NULL default '',
` created_at` int(10) unsigned NOT NULL default 1, 
`updated_at` int(10) unsigned NOT NULL default 0, 
主鍵(`id`), 
UNIQUE KEY `rolename` (`rolename`)
-- 表的結構`ref_aclresources_aclroles`
DROP TABLE IF EXISTS `ref_aclresources_aclroles`; 
如果不存在則建立表`ref_aclresources_aclroles` (hcomm `(M) ncoms `M表ed NOT NULL ,
主鍵(`rsid`,`role_id`)
)預設字元集= utf8 COLLATE=utf8_unicode_ci; 
-- 表的結構`ref_users_aclroles`
DROP TABLE IF EXISTS `jles ref_users_aclroles` (
`user_id` int(10) unsigned NOT NULL auto_increment, 
`role_id` int(10) unsigned NOT NULL, 
PRIMARY KEY (`user_id`,`le_fuser_id` ci;
-- 表的結構`users`
DROP TABLE IF EXISTS `users`; 
建立表`users`(
`id` int(10) unsigned NOT NULL auto_increment,
`email` varcharULL( `password` varchar(64) NOT NULL,
`nickname` varchar(32) NOT NULL 預設'',
`roles` varchar(240) NOT NULL 預設'',
`created_at` int(10) 無符號NOT NULL預設1,
`updated_at` int(10) 無符號NOT NULL 預設0,
PRIMARY KEY (`id`),
唯一金鑰`user_email` (`email`) 
)預設字元集=utf8 COLLATE=utf8_uni_`) 
)預設字元集=utf8 COLLATE=utci

php 類 
 程式碼如下: 
/**
* 簡單的ACL 權限控制功能 

* 表定義 

* 1. 資源定義(rsid,access,desc,created_at,updated_at) 
* 2. 角色定義(id,crelename,lename, fle)
* 3. 資源-角色關聯(rsid,role_id) 
* 4. 用戶-角色關聯(user_id,role_id) 

* 依賴db.php sqlobject.php 

* @author vb2005xu.iteye.com 
*/ 
class AclBase { 
// --- ACL 存取授權 

/****c/****

/** 
* 不允許任何人存取 
*/ 
const EVERYONE = 1; 

/** 
* 允許任何人存取 
*/ 
const HAS_ROLE = 2; 


* 允許 擁有角色的使用者存取 
*/ 
const HAS_ROLE = 2; 


* 允許 不帶角色的使用者存取 
*/ . ** 
* 在 資源-角色關聯 定義的 角色才能存取 
*/ 
const ALLOCATE_ROLES = 4; 

// 定義相關的表名
public $tbResources = 'aclresources'; 
public $tbRoles = 'aclroles'public_bidh; public $tbRefUsersRoles = 'ref_users_aclroles'; 

/** 
* 格式化 資源的存取權並回傳 

* @return int 
*/ 
static function formatAccessValue($access){ 
static $arr = array(selfselNOBODY,$access){ 
static $arr = array(selfselNOBODY,,ONEfself. ::NO_ROLE,self::ALLOCATE_ROLES ); 
返回in_array($access,$arr) ? $access : self::NOBODY; 


/** 
* 建立資源,回資源記錄主鍵 

* @param string $rsid 
* @param int $access 
* @param string $desc */ 
function createResource($rsid,$access,$desc){ 
if (empty($rsid)) return falsesource; = array(
'rsid' => $rsid,
'access' => self::formatAccessValue($access),
'desc' => $desc,
'created_at' =>; CURRENT_TIMESTAMP
); SingleTableCRUD::insert($this->tbResources,$resource); 


/** 
* 修改資源,回成功狀態 

* @param array $resource 
* @return int 
*/ 
function updateResource(array $resource){ 
if (!isset($resource['rsid'])) return false; 

$resource['updated_at'] = CURRENT_TIMESTAMP; 

return SingleTableCRUD::update($this->tbResources,$resource,'rsid'); 


/** 
* 刪除資源 

* @param string $rsid 
* @return int 
*/ 
function deleteResource($rsid){ 
if (empty($rsid)) return false; 
return SingleTableCRUD::delete($this->tbResources,array('rsid'=>$rsid)); 


/** 
* 建立角色,返回角色記錄主鍵 

* @param string $rolename 
* @param string $desc 

* @return int 
*/ 
function createRole($rolename,$desc){ 
if (empty($rolename)) return false; 

$role = array(
'rolename' => $rolename,
'desc' => $desc,
'created_at' => CURRENT_TIMESTAMP
); 

return SingleTableCRUD::insert($this->tbRoles,$role); 


/** 
* 修改角色,返回成功狀態 

* @param array $role 
* @return int 
*/ 
function updateRole(array $role){ 
if (!isset($role['id'])) return false; 

if (isset($role['rolename'])) unset($role['rolename']); 
$role['updated_at'] = CURRENT_TIMESTAMP; 

return SingleTableCRUD::update($this->tbRoles,$role,'id'); 


/** 
* 刪除角色 

* @param int $role_id 
* @return int 
*/ 
function deleteRole($role_id){ 
if (empty($role_id)) return false; 
return SingleTableCRUD::delete($this->tbRoles,array('role_id'=>(int) $role_id)); 


/**
* 為資源指定角色,每次均先全部移除表中相關記錄再插入 

* @param int $rsid 
* @param mixed $roleIds 
* @param boolean $setNull 當角色不存在時,是否將資源從關聯表中清空 
*/ 
function allocateRolesForResource($rsid,$roleIds,$setNull=false,$defaultAccess=-1){ 
if (empty($rsid)) return fsese=-1){ 
if (empty($rsid)) return fsese; 

$roleIds = 標準化($roleIds,','); 
if (empty($roleIds)){
if ($setNull){
SingleTableCRUD::delete($this->tbRefResourcesRoles,array('rsid'=>$rsid)); 

if ($defaultAccess != -1){ 
$defaultAccess = self::formatAccessValue($defaultAccess); 
$this->updateResource(array('rsid'=>$rsid,'access'=>$defaultAccess)); 

回傳 true; 

回傳 false; 


SingleTableCRUD::delete($this->tbRefResourcesRoles,array('rsid'=>$rsid)); 

$roleIds = array_unique($roleIds); 

foreach ($roleIds as $role_id){ 
SingleTableCRUD::insert($this->tbRefResourcesRoles,array('rsid'=>$rsid,'role_id'=>(int)$role_id)); 

回傳 true; 


function cleanRolesForResource($rsid){
if (empty($rsid)) return false; 
return SingleTableCRUD::delete($this->tbRefResourcesRoles,array('rsid'=>$rsid)); 


函數 cleanResourcesForRole($role_id){
if (empty($role_id)) return false; 
return SingleTableCRUD::delete($this->tbRefResourcesRoles,array('role_id'=>(int) $role_id)); 


/** 
* 為角色分配資源,每次均先全部移除表中相關記錄再插入 

* @param int $role_id 
* @param mixed $rsids 

* @return boolean return boolean */ 
函數 allocateResourcesForRole($role_id,$rsids){ 
if (empty($role_id)) return false; 

$role_id = (int) $role_id; 
$rsids = 標準化($rsids,','); 
if (空($rsids)){ 
回傳 false; 


SingleTableCRUD::delete($this->tbRefResourcesRoles,array('role_id'=>$role_id)); 

$rsids = array_unique($rsids); 

foreach ($rsids as $rsid){ 
SingleTableCRUD::insert($this->tbRefResourcesRoles,array('rsid'=>$rsid,'role_id'=>$role_id)); 

回傳true; 


/** 
* 為使用者指定派角色,且每次皆先全部刪除表中相關再記錄插入

* 這裡在使用者很多的時候可能會有效能問題... 後面再想怎麼最佳化 

* @param int $user_id 
* @param mixed $roleIds 

* @return boolean 
*/loccom ($user_id,$roleIds){ 
if (empty($user_id)) return false; 

$user_id = (int) $user_id; 
$roleIds = normalize($roleIds,,','); $roleIds)){ 
return false; 


SingleTableCRUD::delete($this->tbRefUsersRoles,array('user_id'=>$user_id)); ($roleIds as $roleId){ 
SingleTableCRUD::insert($this->tbRefUsersRoles,array('user_id'=>$user_id,'role_id'=>$role_id)); 

return truehrole_id)); 

return true; /** 
* 清除使用者的角色資訊 

* @param int $user_id 

* @return boolean 
*/ 
function cleanRolesForUser($user_id){ 
if (empty($user_id)) return false; 
return SingleTableCRUD::delete($this->tbRefUsersRoles,array('user_id'CRUD::delete($this->tbRefUsersRoles,array('user_id'CRUD::delete=this->tbRefUsersRoles,array('user_id'CRUD::delete=this->tbRefUsersRoles,array('user_id'CRUD>() ) $user_id)); 


/** 
* 清除角色的使用者關聯 

* @param int $role_id 

* @return boolean 
*/ 
function cleanUsersForRole($role_id){ 
if (empty($role_id)) return false tbgturns 區$cm) ,array('role_id'=>(int) $role_id)); 




特定偵測的程式碼如下: 
複製程式碼 程式碼如下: 
/** 
* 對資源進行acl校驗 

* @param string $rsid 資源識別 
* @param array $user 特定使用者,不指定則校驗目前使用者 

* @return leanrs&wid*/funced ,array $user = null){ 

if (empty($rsid)) return false; 
if (!CoreApp::$defaultAcl) { 
CoreApp::$defaultAcl = new AclFlat(); 
CoreApp::$defaultAcl = new AclFlat(); 
CoreApp::$defaultAcl = new AclFlat(); 🎠 = aclGetResource($rsid); 

// 未定義資源的缺省存取策略 
if (!$rsRow) return false; 

CoreApp::writeLog($rsRow,'test'); 

CoreApp::writeLog($rsRow,'test'); 

CoreApp::writeLog($rsRow,'test'); . access'] = AclBase::formatAccessValue($rsRow['access']); 

// 允許任何人存取 
if (AclBase::EVERYONE == $rsRow['access']) return true; 

/不允許任何人存取 
if (AclBase::NOBODY == $rsRow['access']) return false; 

// 取得使用者資訊 
if (empty($user)) $user = isset($_SESSION[' SI-SysUser']) ? $_SESSION['SI-SysUser'] : null; 

// 使用者未登入,則當成無存取權限 
if (empty($user)) return false; 

$user[' roles'] = empty($user['roles']) ? null : normalize($user['roles'],';'); 

$userHasRoles = !empty($user['roles']); 

/** 
* 允許 不帶角色的使用者存取 
*/ 
if (AclBase::NO_ROLE == $rsRow['access']) return $userHasRoles ? false : true; 

/:: 
* 允許 有角色的使用者存取 
*/ 
if (AclBase HAS_ROLE == $rsRow['access']) return $userHasRoles ? true : false; 

// --- 對使用者進行資源 角色校驗 
if ($userHasRoles){user
foreach 
foreach (user[' roles'] as $role_id){ 
if ( aclGetRefResourcesRoles($rsid,$role_id) ) 
return true; 

dump($com); 
}
/ ** 
* 對資源進行acl校驗 

* @param string $rsid 資源識別 
* @param array $user 特定使用者,不指定則校驗目前使用者 

* @return lean*/ 
function aclVerity($rsid ,array $user = null){ 

if (empty($rsid)) return false; 
if (!CoreApp::$defaultAcl) { 
Core::$ defaultAcl = new AclFlat(); 


$rsRow = aclGetResource($rsid); 

// 未定義資源的缺省存取策略rsRow,'test'); 

/* 
* 校驗步驟如下: 

* 1. 先校驗資源本身access 屬性 
* EVERYONE => true,NOBODY => false * 其它的屬性在下面繼續學校驗 
* 2. 從session(或使用者session表)取得角色id集合 
* 3. 若使用者擁有角色則HAS_ROLE => true , NO_ROLE => false;反之亦然 
* 4. 如果資源access == ALLOCATE_LES
* 1. 從快取(或$tbRefResourcesRoles)中取得資源對應的角色id集合 
* 2. 將使用者擁有的角色id集合與資源對應的角色id集合求交集 
* 3. 存在交集=> true;否則= > false 
*/ 

$rsRow['access'] = AclBase::formatAccessValue($rsRow['access']); 

// 允許任何人存取access']) return true; 

// 不允許任何人存取 
if (AclBase::NOBODY == $rsRow['access']) return false; 

// 取得使用者資訊 
if (empty($
user )) $user = isset($_SESSION['SI-SysUser']) ? $_SESSION['SI-SysUser'] : null; 

// 使用者未登入,則當成無存取權限 
if (empty($user )) return false; 

$user['roles'] = empty($user['roles']) ? null : normalize($user['roles'],';'); 

$userHasRoles = !empty ($user['roles']); 

/** 
* 允許 不帶角色的使用者存取 
*/ 
if (AclBase::NO_ROLE == $rsRow['access']) return $userHasRoles ? false: true; 

/**  
* 允許 有角色的使用者存取 
*/ 
if (AclBase::HAS_ROLE == $rsRow['access']) return $userHasRoles ? true : false; 

// --- 對使用者進行資源 角色校驗$userHasRoles){ 
foreach ($user['roles'] as $role_id){ 
if ( aclGetRefResourcesRoles($rsid,$role_id) ) 
return true;

/** 
* 重新產生 角色資源存取控製表 

* @param string $actTable ACL表名稱 
* @param boolean $return 是否回傳重新產生的清單 

* @return mixed*/ 
function aclRebuildACT($actTable ,$return = false){ 
if (empty($actTable)) return false; 

global $g cacheId = null; 

switch($act? ); 
// 轉成雜湊表結構 
if ($rst){ 
$rst = array_to_hashmap($rst,'rsid'); 

break tbcase CoreApp$ cacheId = 'acl-roles'; 
$rst = SingleTableCRUD::findAll(CoreApp::$defaultAcl->tbRoles); 
// 轉成哈希表結構 
if ($rst){ 
$rst = array_to_if ($rst){ 
$rst = array_to_ rst,'id'); 

break; 
case CoreApp::$defaultAcl->tbRefResourcesRoles: 
$cacheId = 'acl-roles_has_resources' ion$h; ); 
if ($rst){ 
$_ = array(); 
foreach ($rst as $row) { 
$ref_id = "{$row['rsid']}{$row[-| 'role_id']}"; 
$_[$ref_id] = $row; 

unset($rst); 
$rst = $_; 

break; ($globalConf['runtime']['cacheDir'] ,$cacheId ,$rst ,true); 

if ($return) return $rst; 

/** 
* 取得 角色資源存取控製表 資料 

* @param string $actTable ACL資料表名稱 

* @return mixed 
*/ 
function aclGet
function actTable){ 
if (empty($actTable)) return false; 

static $rst = array(); 

$cacheId = null; ::
-$actactTableTablec : 
$cacheId = 'acl-resources'; 
break; 
case CoreApp::$defaultAcl->tbRoles: 
$cacheId = 'acl-roles'; 
break; 
$cacheId = 'acl-roles'; 
break; $cacheId = 'acl-roles_has_resources'; 
break; 



if (!$cacheId) return null; 

if (isset($rst[$cacheIdId]) return $
if (isset($rst[$cacheId]) global $globalConf; 
// 900 
$rst[$cacheId] = getCache($globalConf['runtime']['cacheDir'],$cacheId,0); 
if ( !$rst[$cache]
$rst[$cacheId] = aclRebuildACT($actTable,true); 


return $rst[$cacheId]; 

/** 
* 取得 資源 記錄 

* @param string $rsid 

* @return array 
*/ 
function aclGetRe = null; 
if (!$rst){ 
$rst = aclGetACT(CoreApp::$defaultAcl->tbResources); 
if (!$rst) $rst = array(); 

回傳 isset($rst[$rsid]) ? $rst[$rsid] :空; 

/** 
* 取得 角色 記錄 

* @param int $role_id 

* @return array 
*/ 
function aclGetRole($role_id){Yull]; 
if (!$rst){ 
$rst = aclGetACT(CoreApp::$defaultAcl->tbRoles); 
if (!$rst) $rst = array(); 

回傳 isset($rst[$role_id]) ? $rst[$role_id] :空; 

/** 
* 取得 使用者角色關聯 記錄,此方法可以校驗資源是否可被此角色呼叫 

* @param string $rsid 
* @param int $role_id 
**/ 
function aclGetRefResourcesRoles($id),$hrom無效的; 
if (!$rst){ 
$rst = aclGetACT(CoreApp::$defaultAcl->tbRefResourcesRoles); 
if (!$rst) $rst = array(); 

$ref_id = "{$rsid}{$role_id}"; 
CoreApp::writeLog(isset($rst[$ref_id])?$rst[$ref_id]:'nodata',$ref_id); 
返回 isset($rst[$ref_id]) ? $rst[$ref_id] :空; 


http://code.google.com/p/php-excel/downloads/list 迷你好用的 EXCEL xml輸出方案

相關標籤:
php
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板