thinkphp 6 自动获取控制器方法

在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")"
  ]
]

获取成功

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
了解了您的需求,我可以为您提供一个思路,假设您使用的是 ThinkPHP 6 框架,您可以通过以下步骤实现: 1.使用反射机制获取已有控制器的类名和方法名。 ```php $controllerName = 'app\controller\YourController'; // 已有控制器的类名 $methodName = 'yourMethod'; // 已有控制器方法名 $reflectionClass = new \ReflectionClass($controllerName); // 实例化反射类 $reflectionMethod = $reflectionClass->getMethod($methodName); // 获取反射方法 ``` 2.通过反射机制获取已有控制器方法的参数列表。 ```php $params = []; foreach($reflectionMethod->getParameters() as $param) { if ($param->isDefaultValueAvailable()) { $params[] = $param->getDefaultValue(); } else { $params[] = null; } } ``` 3.通过反射机制获取已有控制器方法的注释,包括路由和参数注释。 ```php $docComment = $reflectionMethod->getDocComment(); preg_match('/@route\W+(.*)/', $docComment, $routeMatch); $route = isset($routeMatch[1]) ? $routeMatch[1] : ''; preg_match_all('/@param\W+(\w+)\W+(\$[a-zA-Z0-9_]+)/', $docComment, $paramMatches); $paramsDoc = []; foreach ($paramMatches[2] as $index => $paramName) { $paramsDoc[$paramName] = $paramMatches[1][$index]; } ``` 4.使用获取到的信息,动态生成新的控制器方法。 ```php $newMethodName = 'newMethod'; // 新的控制器方法名 $newControllerContent = <<<CONTROLLER <?php namespace app\controller; use think\Controller; class NewController extends Controller { /** * $docComment */ public function $newMethodName($paramsDoc) { // 在此处编写新的控制器方法逻辑 } } CONTROLLER; file_put_contents('app/controller/NewController.php', $newControllerContent); // 将新的控制器文件写入磁盘 ``` 需要注意的是,以上代码仅为思路示例,具体实现可能需要根据您的需求进行调整。同时,自动生成的代码需要您自己进行调试和测试,以确保代码的正确性和稳定性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

php肖彬

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值