通过控制器的注释自动生成
<?php
namespace lib;
/**
* 权限类
* 基于用户组
* SESSION值未设置,判断是否无需登陆
* SESSION值已设置,判断是否有权限
*/
class auth
{
//权限组 表结构
private $tbGroup = array(
'tbName' => 'auth_group',
'idName' => 'id',
'groupName' => 'name',
'descName' => 'description',
'powerName' => 'power_value',
);
//权限值 表结构
private $tbPower = array(
'tbName' => 'auth_power',
'idName' => 'id',
'moduleName' => 'name',
'pathName' => 'module_path',
'levelName' => 'level',
);
//没有登录且没有权限将被设为false
private $isLogin = true;
//权限的SESSION键名
private $sessionName = 'adminAuth';
/**
* 设置SESSION键名
* @param [type] $sessionName [description]
*/
//设置SESSION键名
public function setSessionName($sessionName)
{
$this->sessionName = $sessionName;
return $this;
}
/**
* 获取SESSION键名
* @param [type] $sessionName [description]
*/
//获取SESSION键名
public function isLogin()
{
return $this->isLogin;
}
/**
* 设置权限组表字段名
* @param [type] $tbGroup [description]
*/
//设置权限组表字段名
public function setGroupFields($tbGroup)
{
$this->tbGroup = $tbGroup;
return $this;
}
/**
* 设置权限值表字段名
* @param [type] $tbPower [description]
*/
//设置权限值表字段名
public function setPowerFields($tbPower)
{
$this->tbPower = $tbPower;
return $this;
}
/**
* 根据用户组ID 设置权限
* @param int $groupId 权限组id
*/
//设置权限
public function setAuth($groupId)
{
$where1[$this->tbGroup['idName']] = $groupId;
$power_value = D($this->tbGroup['tbName'])->where($where1)->find($this->tbGroup['powerName']);
if (!isset($_SESSION)) {session_start();}
// -1为超级管理员 拥有所有权限
if ($power_value == -1) {$_SESSION[$this->sessionName] = -1;return;}
$field = array(
$this->tbPower['idName'],
$this->tbPower['pathName'],
$this->tbPower['levelName'],
);
$where2[$this->tbPower['levelName'] . ' >'] = 1;
$powerVal = explode(',', $power_value);
//取出level大于1的数据,然后去掉level等于3且$powerVal不存在的数据
$powerAll = D($this->tbPower['tbName'])->field($field)->where($where2)->select();
$authArr = array();
foreach ($powerAll as $key => $value) {
if ($value[$this->tbPower['levelName']] == 3) {
if (in_array($value[$this->tbPower['idName']], $powerVal)) {
$authArr[$value[$this->tbPower['pathName']]] = $value[$this->tbPower['levelName']];
}
} else {
$authArr[$value[$this->tbPower['pathName']]] = $value[$this->tbPower['levelName']];
}
}
$_SESSION[$this->sessionName] = $authArr;
}
/**
* 检查权限
* @return bool true/false
*/
//检查权限
public function checkAuth()
{
$controllerName = CONTROLLER_NAME;
$actionName = ACTION_NAME;
$n = func_num_args();
if ($n >= 2) {
$controllerName = func_get_arg(0);
$actionName = func_get_arg(1);
} elseif ($n == 1) {
$actionName = func_get_arg(0);
}
$moduePath = strtolower($controllerName . '/' . $actionName);
// session没有被设置,查询数据库是否为nologin权限
if (!isset($_SESSION[$this->sessionName])) {
//数据库查询
$where[$this->tbPower['pathName']] = $moduePath;
$where[$this->tbPower['levelName']] = 1;
$ret = D($this->tbPower['tbName'])->where($where)->count();
if ($ret) {
return true;
} else {
$this->isLogin = false;
}
} else {
// session值为-1是超级管理员 ,拥有所有权限
if ($_SESSION[$this->sessionName] == -1) {
return true;
}
//匹配nocheck或rolecheck权限
if (isset($_SESSION[$this->sessionName][$moduePath])
and $_SESSION[$this->sessionName][$moduePath] > 1) {
return true;
}
}
return false;
}
/**
* 清除SESSION权限
* @return void
*/
//清除权限 清除SESSION
public function clearAuth()
{
unset($_SESSION[$this->sessionName]);
}
/**
* 获取所有模块
* 并写入数据库
*/
//获取所有模块,在开发模式下使用
public function getModuleOnlyDebug()
{
//定义记录类数组
$classNameArr = array();
//定义方法数组
$methodsArr = array();
//定义控制器数组
$controllerArr = array();
//获取控制器目录
$controllerDir = APP . 'controller';
if ($fileList = opendir($controllerDir)) {
while ($fileName = readdir($fileList)) {
if (!is_dir($fileName)) {
$classNameArr[] = str_replace('.class.php', '', $fileName);
}
}
closedir($fileList);
}
//遍历类数组
foreach ($classNameArr as $className) {
$classPathName = "c\\$className";
$class = new \ReflectionClass($classPathName);
//获取类的注释
$clsComment = $class->getDocComment();
$clsCommentArr = $this->_getComment($clsComment, $className);
$controllerArr[] = array(
$this->tbPower['pathName'] => $className,
$this->tbPower['moduleName'] => $clsCommentArr[0],
$this->tbPower['levelName'] => $clsCommentArr[1],
);
//获取类的方法
$methods = $class->getMethods();
foreach ($methods as $method) {
//过滤掉父类、非公共、非静态方法
if ($classPathName == $method->class
and $method->ispublic()
and $method->isStatic()
) {
//获取方法的注释
$methodComment = $method->getDocComment();
$methodCommentArr = $this->_getComment($methodComment, $className . '/' . $method->name);
$controllerArr[] = array(
$this->tbPower['pathName'] => $className . '/' . $method->name,
$this->tbPower['moduleName'] => $methodCommentArr[0],
$this->tbPower['levelName'] => $methodCommentArr[1],
);
}
}
}
//创建数据表
$this->_createTable();
//写入数据库
$this->_insert($controllerArr);
return $controllerArr;
}
/**
* 从类或方法的注释获取
* 以“|”分割 moduleName|level
* level为权限级别0表示类无权限意义:
* 1、noLogin; 2、noCheck; 3、roleCheck
* 1、无需登录;2、检查登录;3、检查权限
* 类的level不填写取0
* 方法的level不填写取3
*/
private function _getComment($comment, $name)
{
$tmp = explode(PHP_EOL, $comment);
$str = isset($tmp[1]) ? $tmp[1] : $name;
$search = array('#', '/', '*', ' ', "\t", "\r", "\n", "\\", '\'', "'", '`');
$str = str_replace($search, array(), $str);
$arr = explode('|', $str);
empty($arr[0]) ? $arr[0] = strtoupper($name) : null;
strstr($name, '/') !== false ?: $arr[1] = '0'; //如果是类不是方法
isset($arr[1]) ?: $arr[1] = '3';
strtoupper($arr[1]) == 'NOLOGIN' ? $arr[1] = '1' : null;
strtoupper($arr[1]) == 'NOCHECK' ? $arr[1] = '2' : null;
in_array($arr[1], array('1', '2', '3', '0')) ?: $arr[1] = '3';
return $arr;
}
/**
* 将模块名称写入数据库
*/
//将模块名称写入数据库
private function _insert($controllerArr)
{
$P = $this->tbPower;
$pre = C('DB_PREFIX');
foreach ($controllerArr as $D) {
$sql = "INSERT INTO `{$pre}{$P['tbName']}`
(`{$P['pathName']}`,`{$P['moduleName']}`,`{$P['levelName']}`) VALUES ('{$D[$P['pathName']]}','{$D[$P['moduleName']]}','{$D[$P['levelName']]}') ON DUPLICATE KEY UPDATE `{$P['moduleName']}`='{$D[$P['moduleName']]}',`{$P['levelName']}`='{$D[$P['levelName']]}';";
D()->submit($sql);
}
}
/**
* 创建数据表
* @return void
*/
//创建数据表
private function _createTable()
{
//检查数据表是否存在
//获取表格前缀
$pre = C('DB_PREFIX');
$G = $this->tbGroup;
$P = $this->tbPower;
//如果没有用户组和资源数据表,则自动创建
$sqlGroup = "CREATE TABLE IF NOT EXISTS `" . $pre . $G['tbName'] . "` (
`" . $G['idName'] . "` INT(9) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'ID',
`" . $G['groupName'] . "` VARCHAR(255) NOT NULL COMMENT '权限组名',
`" . $G['descName'] . "` VARCHAR(255) NOT NULL COMMENT '权限组描述',
`" . $G['powerName'] . "` VARCHAR(3000) NOT NULL COMMENT '权限值',
PRIMARY KEY (`" . $G['idName'] . "`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 COMMENT '角色权限表';";
$sqlPower = "CREATE TABLE IF NOT EXISTS `" . $pre . $P['tbName'] . "` (
`" . $P['idName'] . "` INT(9) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'ID',
`" . $P['pathName'] . "` VARCHAR(255) NOT NULL UNIQUE COMMENT '模块路径',
`" . $P['moduleName'] . "` VARCHAR(255) NOT NULL COMMENT '模块名称',
`" . $P['levelName'] . "` TINYINT( 1 ) UNSIGNED NOT NULL DEFAULT '3' COMMENT '模块级别|0表示类;1=noLogin=无需登录;2=noCheck=登录权限;3=roleCheck=权限检查',
PRIMARY KEY (`" . $P['idName'] . "`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 COMMENT '权限模块';";
$sqlSuperAdmin = "INSERT IGNORE INTO `" . $pre . $G['tbName'] . "` (`" . $G['idName'] . "`, `" . $G['groupName'] . "`, `" . $G['descName'] . "`, `" . $G['powerName'] . "`) VALUES ('1', '超级管理员','拥有系统所有管理权限,不可修改', '-1');";
D()->submit($sqlGroup);
D()->submit($sqlPower);
D()->submit($sqlSuperAdmin);
}
}