利用php反射机制 获取权限
来源:互联网 发布:单反入门推荐知乎 编辑:程序博客网 时间:2024/06/05 02:55
之前实现了一个基于角色的权限控制,需要后台手动添加权限,当系统庞大的时候,一条条的加无疑是一场灾难…后来看到公司的权限系统利用php反射机制获取权限,感觉很不错,自己查了下php的反射机制,应用在了自己博客中。 本文代码环境为laravel5.4
一、数据库表结构
截个图吧…
pri_name:权限名
pri_desc:权限描述
module_name:模块名
controller:控制器名
action_name:方法名
##二、一些约定
1.代码编写时需要以下的格式
“`php
/**
* @name 添加操作
* @desc 添加操作
* @param Request
{
if(
return response()->json(msg(‘error’,’该管理员已存在!’));
}
if(
return response()->json(msg(‘success’,’添加成功!’));
}
return response()->json(msg(‘error’,’添加失败!’));
}
“`
需要注释加上@name @desc,@name是必须的
2.还需要配置你需要控制的模块,在config/app.php 加上
/** * 自定义配置 */ 'ACCESS_CHECK_MODULE' => env('ACCESS_CHECK_MODULE','admin'), 'name_space' =>'App\Http\Controllers',
`
.env 文件写上哪些模块需要权限控制
ACCESS_CHECK_MODULE = 'Admin
3.被控制的模块路由地址必须和控制器方法名吻合,比如:
//角色Route::any('/role/add','RoleController@add');Route::post('/role/addOperate','RoleController@addOperate');Route::get('/role/index','RoleController@index');Route::get('/role/edit/{id}','RoleController@edit')->where('id', '[0-9]+');Route::post('/role/editOperate','RoleController@editOperate');Route::post('/role/delete','RoleController@delete'); ``` ##三、实现PBAC类 这个类的功能只是获取并返回权限 代码如下:```php <?php/** * @name 利用反射获取权限树(路由) * @author [ycp] <[820363773@qq.com]> * Author: ycp * Date: 2017/6/14 * Time: 10:35 * Created by PhpStorm. */namespace App\Models;use ReflectionClass;class Rbac{ public function getAccess(){ //1.获取所有控制器 $modules = config('app.ACCESS_CHECK_MODULE'); $modules = explode(',',$modules); $controllers =[]; $pris = []; //获取基础控制器的方法 $base_controller = config('app.name_space').'\\'.'Controller'; $reflection = new ReflectionClass($base_controller); $action_base_names = $reflection->getMethods(); $action_base_name=[]; foreach ($action_base_names as $v){ $action_base_name[]=$v->name; } //循环模块 foreach ($modules as $mk=>$mv){ $controllers = $this->getController($mv); if($controllers == null){ continue; } //循环控制器 foreach ($controllers as $con){ $con_name = str_replace('Controller','',basename($con)); $reflection2 = new ReflectionClass($con); $action_names = $reflection2->getMethods(); //循环方法 foreach ($action_names as $ak=>$av){ $av_real = $av->name; $desc = $av->getDocComment(); //控制器名称 if (!preg_match('/@name\s+(\w+)/u', $desc, $catch)) continue; $name = $catch[1]; //控制器描述 $description = preg_match('/@desc\s+(\w+)/u', $desc, $catch) ? $catch[1] : ''; if(in_array($av_real,$action_base_name) || $av_real == '__construct'){ continue; }else{ $pris[] = [ 'module_name' =>$mv, 'controller' =>$con_name, 'action_name' =>$av_real, 'pri_name' =>$name, 'pri_desc' =>$description ]; } } } } return $pris; } /** * 获取所有控制器名称 * @param string $module * @return array */ protected function getController($module){ if(empty($module)){ return null; } $module_path = app_path('Http\Controllers').'/'.$module;//模块路径 $module_path = str_replace('\\','/',$module_path); if(!is_dir($module_path)) { return null; }; $module_path .= '/*.php'; $ary_files = glob($module_path); $files= []; foreach ($ary_files as $file){ if(is_dir($file) || basename($file,'.php') =='LoginController'){ continue; }else{ $files[]=config('app.name_space').'\\'.$module.'\\'.basename($file,'.php'); } } return $files; }} ```<div class="se-preview-section-delimiter"></div>##四、添加权限<div class="se-preview-section-delimiter"></div>```php /** * @name 系统权限添加入库 * @desc 系统权限添加入库 * @return mixed */ public function refreshPri() { $rbac = new Rbac(); $pris = $rbac->getAccess(); $ids = [] ; //更新或者添加的ID foreach ($pris as $k=>$v){ //添加或者更新已有权限 $pri = $this->updateOrCreate([ 'module_name' =>$v['module_name'], 'controller' =>$v['controller'], 'action_name' =>$v['action_name'] ],[ 'pri_name' =>$v['pri_name'], 'pri_desc' =>$v['pri_desc'] ]); $ids[] = $pri->id; } //去掉删除的权限 $old_ids = json_decode($this->pluck('id'),true); $delete_ids = array_diff($old_ids,$ids); foreach ($delete_ids as $v){ $this->destroy($v); } return true; }
到这里php处理得就差不多了,然后就是前段展示的问题
五、展示权限
截个图…
六、权限控制
权限检测都在中间件中进行,定义AdminNeedsPermission中间件
<?phpnamespace App\Http\Middleware;use Closure;class AdminNeedsPermission{ /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */ public function handle($request, Closure $next) { //公共包不做权限验证 if($request->is('common/*')){ return $next($request); } if(checkPri($request->path())){ if(\Request::ajax()){ return response()->json(msg('error','您没有权限访问!')); } return redirect('admin')->with(['SYS_INFO'=>'您没有权限访问!']); } return $next($request); }}
checkPri方法:添加到辅助方法helper中
/** * 检测权限 */if ( ! function_exists('checkPri')){ function checkPri($url){ if($url == 'admin'){//首页不验证 return false; } $pris = SC::getUserAccess(); if(count($pris)>0){ if(!is_array($url)){ $url = explode('/',$url); } foreach ($pris as $pri){ if($pri->admin_id ===1){ return false; } if(strtolower($url[0]) == strtolower($pri->module_name) && strtolower($url[1]) == strtolower($pri->controller) && strtolower($url[2]) == strtolower($pri->action_name)){ return false; } } } return true; }}
总结:实现起来并不复杂,从此不必手动一个个添加权限了
以上代码都在项目https://github.com/ycp19940225/blog可以找到
个人博客:YCP-BLOG
——END
/** * 检测权限 */if ( ! function_exists('checkPri')){ function checkPri($url){ if($url == 'admin'){//首页不验证 return false; } $pris = SC::getUserAccess(); if(count($pris)>0){ if(!is_array($url)){ $url = explode('/',$url); } foreach ($pris as $pri){ if($pri->admin_id ===1){ return false; } if(strtolower($url[0]) == strtolower($pri->module_name) && strtolower($url[1]) == strtolower($pri->controller) && strtolower($url[2]) == strtolower($pri->action_name)){ return false; } } } return true; }}
总结:实现起来并不复杂,从此不必手动一个个添加权限了
以上代码都在项目https://github.com/ycp19940225/blog可以找到
个人博客:YCP-BLOG
——END
- 利用php反射机制 获取权限
- php 利用反射API获取类信息
- c#反射机制学习和利用反射获取类型信息
- php反射机制以及利用php反射机制实现可插拔可扩展的插件架构
- 利用反射机制动态获取对象属性名称及数据类型
- 利用反射机制动态获取对象属性名称及数据类型
- 利用反射机制获取android系统属性值
- android中利用Java反射机制获取系统相机对象
- Android--利用Java反射机制获取视频帧图像
- Android 应用利用反射机制获取/设置系统属性值
- PropertyUtils.getPropertyDescriptors利用反射机制获取类中的属性
- 利用反射机制获取Enum属性的name或者value
- 利用java反射机制获取一个类中信息
- 利用php反射机制实现动态代理模式
- php反射获取方法及其注释控制权限
- PHP的反射机制
- php反射机制
- PHP的反射机制
- activemq配置主从
- 开源的连接池技术DBCP与c3p0
- Android NDK(1)
- 8.11博客皮肤测试
- React-navigation 官方文档中文翻译(一) Hello Mobile Navigation
- 利用php反射机制 获取权限
- java NIO 相关资料
- 关于Eclipse的Team菜单中没有SVN选项的问题
- 关于IntelliJ IDEA 无法编辑代码的问题
- crontab 检测是否正常运行
- 我又回来啦!
- 用Python学《微积分B》(Chapter 4-2 Derivate and Differential)
- web.xml标签详解
- 1004. 成绩排名 (20)