記錄 2015-12-18 學習 ThinkPHP 框架過程中,實現基於角色的訪問控制(RBAC)的數據庫設計、數據初始化、後台邏輯與前端模板渲染全流程。
sw_managerCREATE TABLE `sw_manager` (
`mg_id` int(11) NOT NULL AUTO_INCREMENT,
`mg_name` varchar(32) NOT NULL,
`mg_pwd` varchar(32) NOT NULL,
`mg_time` int(10) unsigned NOT NULL COMMENT '註冊時間',
`mg_role_id` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '角色ID',
PRIMARY KEY (`mg_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
示例數據:
| mg_id | mg_name | mg_pwd | mg_time | mg_role_id |
|---|---|---|---|---|
| 0 | creatint | 123 | 2587413547 | 1 |
| 1 | yotaku | 123 | 258744984 | 4 |
sw_authCREATE TABLE `sw_auth` (
`auth_id` smallint(6) unsigned NOT NULL AUTO_INCREMENT,
`auth_name` varchar(20) NOT NULL COMMENT '權限名稱',
`auth_pid` smallint(6) unsigned NOT NULL COMMENT '父ID',
`auth_c` varchar(32) NOT NULL DEFAULT '' COMMENT '控制器',
`auth_a` varchar(32) NOT NULL DEFAULT '' COMMENT '操作方法',
`auth_path` varchar(32) NOT NULL COMMENT '全路徑',
`auth_level` tinyint(4) NOT NULL DEFAULT '0' COMMENT '級別',
PRIMARY KEY (`auth_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
字段含義:auth_level=0 為頂級模塊,=1 為具體操作節點。
sw_roleCREATE TABLE `sw_role` (
`role_id` smallint(6) unsigned NOT NULL AUTO_INCREMENT,
`role_name` varchar(20) NOT NULL COMMENT '角色名稱',
`role_auth_ids` varchar(128) NOT NULL DEFAULT '' COMMENT '權限ID列表,如 1,3,9',
`role_auth_ac` text COMMENT '控制器-操作對,如 Goods-show,Goods-cate',
PRIMARY KEY (`role_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `sw_auth` VALUES
(100, '產品中心', 0, '', '', '100', 0),
(101, '高級管理', 0, '', '', '101', 0),
(102, '系統管理', 0, '', '', '102', 0),
(103, '權限管理', 0, '', '', '103', 0);
INSERT INTO `sw_auth` VALUES
(104, '產品展示', 100, 'Goods', 'show', '100-104', 1),
(105, '最新產品', 100, 'Goods', 'showlist', '100-105', 1),
(106, '分類管理', 100, 'Goods', 'cate', '100-106', 1),
(107, '用戶留言', 101, 'Goods', 'words', '101-107', 1),
(108, '留言簿', 101, 'Goods', 'wordsbook', '101-108', 1),
(109, '基本設置', 102, 'Goods', 'set', '102-109', 1),
(110, '樣式管理', 102, 'Goods', 'css', '102-110', 1),
(111, '用戶列表', 103, 'Goods', 'userlist', '103-111', 1),
(112, '角色管理', 103, 'Goods', 'role', '103-112', 1),
(113, '權限列表', 103, 'Goods', 'auth', '103-113', 1);
INSERT INTO `sw_role` VALUES
(10, '站主', '100,101,102,103,104,105,106,107,108,109,110,111,112,113',
'Goods-show,Goods-showlist,Goods-cate,Goods-words,Goods-wordsbook,Goods-set,Goods-css'),
(11, '管理員', '100,102,104,105,109',
'Goods-showlist,Goods-cate,Goods-css'),
(12, '版主', '100,101,103,106,108,113',
'Goods-show,Goods-set');
// Index 控制器 left 方法
$mg_id = session('admin_id');
$manager_info = D('Manager')->find($mg_id);
$role_id = $manager_info['mg_role_id'];
$role_info = D('Role')->find($role_id);
$auth_ids = $role_info['role_auth_ids'];
// 查詢頂級模塊
$auth_infoA = D('Auth')->where("auth_level=0 AND auth_id IN ($auth_ids)")->select();
// 查詢二級節點
$auth_infoB = D('Auth')->where("auth_level=1 AND auth_id IN ($auth_ids)")->select();
$this->assign('auth_infoA', $auth_infoA);
$this->assign('auth_infoB', $auth_infoB);
$this->display();
模板 left.html(Smarty 語法):
{foreach $auth_infoA as $k=>$v}
{$v.auth_name}
{/foreach}
配合 JavaScript expand(id) 控制二級菜單展開/收起,實現經典左側導航樹。
此 RBAC 實現採用「角色-權限ID列表」與「控制器-操作對」雙重存儲,查詢時按層級分兩次 SQL 獲取,模板雙重循環渲染樹狀菜單。優點:邏輯清晰、易擴展;缺點:權限變更需同步兩字段、深層級菜單需遞歸查詢。後續可優化為 Closure Table 或引入 Casbin 等專業授權庫。