Z-PHP权限类 auth.class.php

分享 未结
1 339
番茄
番茄 VIP 1 2018-03-31
悬赏:0

Z-PHP权限类 auth.class.php

通过控制器的注释自动生成

<?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);
    }
}









回帖