在PHP中 经常使用到Auth
如何利用 thinkphp 6 自带的中间件 自动获取控制器、方法及注释信息
操作如下
创建中间件
自动创建中间件
执行cmd命令 php think make:middleware common@NodeMiddleware
生成如下代码
<?php
declare (strict_types = 1);
namespace app\common\middleware;
use ReflectionClass;
class NodeMiddleware
{
/**
* 处理请求
*
* @param \think\Request $request
* @param \Closure $next
* @return Response
*/
public function handle($request, \Closure $next)
{}
}
首先需要在 handle 中 设置个要获取的文件夹
public function handle($request, \Closure $next)
{
$path = app()->getRootPath()."app";
// 将节点存入 请求数据中
$request->Node = $this->getNodeTree($path);
// 别忘了加上
return $next($request);
}
获取全部节点列表
/**
**************************************
* @Title 获取全部节点列表
* @param string $pathDir
* @param array $nodes
* @return void
***************************************
* @author Xiaobin
* @Email 850009244@qq.com
*/
private static function getNodeTree( string $pathDir , array $nodes = [])
{
foreach (self::scanDirFile($pathDir) as $filename) {
$matches = [];
if (!preg_match('|/(\w+)/controller/(\w+)|', str_replace(DIRECTORY_SEPARATOR, '/', $filename), $matches) || count($matches) !== 3) {
continue;
}
$filename = substr_replace($filename , "" , strpos($filename , $pathDir. DIRECTORY_SEPARATOR ) , strlen($pathDir . DIRECTORY_SEPARATOR ));
$filename = substr_replace($filename , "" , strpos($filename , '.php' ) , strlen('.php'));
$fileArray = explode("/" , $filename);
if(in_array($fileArray[0] , Config("app.deny_app_list") )) continue;
$className = self::setNodeArray($fileArray);
if (!class_exists($className['module'])) {
continue;
}
foreach (get_class_methods($className['module']) as $funcName)
{
if (strpos($funcName, '_') !== 0 && $funcName !== 'initialize') {
$path = explode("/",$className['url']);
$app = $path[0];
$nodess = [
'url' => $className['url'] . DIRECTORY_SEPARATOR . $funcName,
'module' => $className['module'],
'app' => $app,
'controller'=> $path[1],
'action' => $funcName,
'needLogin' => self::isNotNeedLogin($className['module'] , $funcName) ? 1 : 0
];
$nodes[] = array_merge($nodess ,self::_ReflectionClass($className['module'] , $funcName));
}
}
}
return $nodes;
}
// 将数据转为驼峰
private static function isNotNeedLogin( string $class , string $action)
{
$classObject = invoke($class);
return in_array($action , $classObject->notNeedLogin);
}
路径重组
private static function setNodeArray( array $fileArray)
{
$array = [];
$array['module'] = '\\app\\' . implode("\\",$fileArray);
unset($fileArray[1]);
$fileArray = array_values($fileArray);
if(count($fileArray) < 3) {
$array['url'] = implode("/",$fileArray);
} else {
$app = $fileArray[0];
unset($fileArray[0]);
$fileArray = array_values($fileArray);
$array['url'] = $app . DIRECTORY_SEPARATOR . implode(".",$fileArray);
}
return $array;
}
获取全部节点信息
/**
**************************************
* @Title 获取全部节点
* @param string $dirPath
* @param array $data
* @param string $ext
* @return array
***************************************
* @author Xiaobin
* @Email 850009244@qq.com
*/
private static function scanDirFile( string $dirPath , array $data = [] , string $ext = 'php')
{
foreach ( scandir($dirPath) as $dir)
{
if (strpos($dir, '.') === 0) {
continue;
}
$tmpPath = realpath($dirPath . DIRECTORY_SEPARATOR . $dir);
if (is_dir($tmpPath)) {
$data = array_merge($data, self::scanDirFile($tmpPath));
} elseif (pathinfo($tmpPath, 4) === $ext) {
$data[] = $tmpPath;
}
}
return $data;
}
通过反射 读取 注解信息
/**
**************************************
* @Title 通过反射读取
* @return void
***************************************
* @author Xiaobin
* @Email 850009244@qq.com
*/
private static function _ReflectionClass(string $module , string $class)
{
$array = [];
$lectionClass = new ReflectionClass($module);
$classObject = invoke($module);
preg_match_all('/@(\w+)\s*([^\s]*)/i', $lectionClass->getMethod($class)->getDocComment(), $matches);
foreach ( $matches[1] as $k => $v){
$array[$v] = $matches[2][$k];
}
return $array;
}
测试
/**
**************************************
* @title 首页
* @return void
***************************************
* @author Xiaobin
* @Email 850009244@qq.com
* @CreateTime 2023/2/13 11:35:38
****************************************
* 项目采用自动获取 title 标题 author 作者 Email 作者邮箱 CreateTime 创建时间
* 当 存在 编辑时间: 时 将对项目自动写入 项目 更新日志当中 desc 为项目编辑后的内容信息
* @UpdateTime false
* @UpdateDesc false
*
* 其他配置 如 注解路由@Route("hello/:name") @Validate(IndexValidate::class,scene="create",batch="true")
*
*/
public function index()
{
dump($this->request->Node);die;
return $this->view->fetch();
}
^ array:3 [▼
0 => array:15 [▼
"url" => "admin/Index/index"
"module" => "\app\admin\controller\Index"
"app" => "admin"
"controller" => "Index"
"action" => "index"
"needLogin" => 1
"title" => "首页"
"return" => "void"
"author" => "Xiaobin"
"Email" => "850009244@qq.com"
"CreateTime" => "2023/2/13"
"UpdateTime" => "false"
"UpdateDesc" => "false"
"Route" => "("hello/:name")"
"Validate" => "(IndexValidate::class,scene="create",batch="true")"
]
1 => array:15 [▼
"url" => "admin/Index/set"
"module" => "\app\admin\controller\Index"
"app" => "admin"
"controller" => "Index"
"action" => "set"
"needLogin" => 0
"title" => "编辑"
"return" => "void"
"author" => "Xiaobin"
"Email" => "850009244@qq.com"
"CreateTime" => "2023/2/13"
"UpdateTime" => "false"
"UpdateDesc" => "false"
"Route" => "("hello/:name")"
"Validate" => "(IndexValidate::class,scene="create",batch="true")"
]
2 => array:15 [▼
"url" => "admin/Login/login"
"module" => "\app\admin\controller\Login"
"app" => "admin"
"controller" => "Login"
"action" => "login"
"needLogin" => 0
"title" => "管理员登录"
"return" => "void"
"author" => "Xiaobin"
"Email" => "850009244@qq.com"
"CreateTime" => "2023/2/13"
"UpdateTime" => "false"
"UpdateDesc" => "false"
"Route" => "("hello/:name")"
"Validate" => "(IndexValidate::class,scene="create",batch="true")"
]
]
获取成功