• 沈逸老师PHP魔鬼特训笔记(1213) --异形


      我们常见的访问约定方式一:/index.php?m=xx&a=oo.其中m和a是固定参数名,

      1、m的值(假设xx是index):代表我们的代码文件名、类名肯定和index有关

      2、a的值:代表代码文件中有个方法叫做OO。

      日常工作中为了规范,我们会把XX设定为一个类。

      常见约定访问方式二:/index.php/xxx/ooo

      其实这个和前面类似,我们可以通过index.php获取当前用户访问的整个url地址,通过各种街区或则$_SERVER['PATH_INFO']后,获取/xxx/ooo这个字符串。而XXX这里代表某类,ooo代表某方法。

      几个注意事项:1、如果你发现你的php不支持path_info请打开。

                            2、如果index.php后面不加path参数,则这个变量是不存在的。因此要做判断。

               3、到了生产环境中可以使用htaccess对所有访问全部重新到path_info 模式的地址。

      以上是常见框架的基本原理,但这不是我们想要的。

      先来看看我们的基本约定:

      1、凡是所谓的控制器,都必须是xxx.class.php这样的形式。

      2、类名和文件名(第一段)必须一致。

      3、在类名上必须写上注释

    /**
    *@Controller //代表是一个控制器,否则它仅仅是一个普通类
    */

       接下我们开始一个新的实验,在GOD里创建一个新的类叫god_mvc用于处理这些Controller。主要实现下面这些功能:1、构造函数,接受类名参数,用户创建反射。2、判断函数,用于判断是否controller.3、获取所有的方法的注释,解析@RequestMapping(里面的内容)。

    <?php
    
    namespace coreframe;
    class god_mvc
    {
        public $className="";//传入的类名
        public $classComment="";
        public $classMethods=array();
        function __construct($cname)        //接受一个classname(类名)
        {
            $this->className=$cname;
    
            $f=new ReflectionClass($cname);
            $this->classComment=$f->getDocComment();
            $this->classMethods=$f->getMethods();//获取类里面所有的方法集合 ,返回一个 方法对象数组
        }
        function isController()
        {
            return preg_match("/@Controller/",$this->classComment);
        }
        function getReqestMapping()
        {
            $result=array();
            foreach($this->classMethods as $method)
            {
                $get_res=$this->genReqestMappingResult($method);
                if($get_res)
                {
                    $result=array_merge($result,$get_res);
                }
            }
            return $result;
        }
        function genReqestMappingResult($m)
        {
            //index.php/getme/eme/age
            //@RequestMapping("/getme",Method=GET);
            if(preg_match('/@RequestMapping("(?<RequestUrl>.{2,50})",Method=(?<RequestMethod>w{3,8}));/',$m->getDocComment(),$result))
            {
                return array($result['RequestUrl']=>array(
                    'RequestMethod'=>$result['RequestMethod'],
                    "Class"=>$this->className,
                    'Method'=>$m->getName()
                ));
            }
            return false;
        }
    }
    
    ?>

      god_frame文件中的compile()方法我们增加获取加载所有类的代码。

    function compile(){ //将code里的重复变量读取出来处理掉
           $_files = scandir($this -> project_folder.'/code');
           foreach($_files as $_file){
               if(preg_match("/w+.var|func.php$/i",$_file)){
                   require ($this->project_folder.'/code/'.$_file);
                   unset($_file);
               }
           }
            unset($_files);//销毁这个无效的变量
            //var_export(get_defined_vars());
            
            $result = '<?php '.PHP_EOL
                .'ectract('.var_export(get_defined_vars(),1).');';
            file_put_contents($this->project_folder."/vars.php",$result);
    
            $getFunc = get_defined_functions()["user"];
            $getFunc = array_slice($getFunc,6); //去掉GOD程序创建的函数
            $func_set="";
            foreach ($getFunc as $func){
                $f = new ReflectionFunction($func);
                $start = $f->getStartLine();    //获取该函数的启始行号
                $end = $f->getEndLine();        //获取该函数的末尾行号
                $fileList = file($f-> getFileName());
                $func_set.=implode(array_slice($fileList,$start-1,$end-$start+1));
            }
            
            //生成到项目文件夹,文件名是functions
            file_put_contents($this->project_folder."/functions",'<?php //compiled by GOD '.date('Y-m-d h:i:s').PHP_EOL.$func_set);
           
            /*$f = new ReflectionFunction('showName');
            $start = $f->getStartLine();    //获取该函数的启始行号
            $end = $f->getEndLine();        //获取该函数的末尾行号
            $fileList = file($f-> getFileName());
            echo implode(array_slice($fileList,$start-1,$end-$start+1));*/
            
            //获取已经加载的所有类
            $class_set=get_declared_classes();       $class_set=array_slice($class_set,array_search(__CLASS__,$class_set)+1);
            $result=array();
            foreach($class_set as $class)
            {
                $mvc=new god_mvc($class);
                if($mvc->isController())
                {
                    $mp=$mvc->getReqestMapping();
                    $result=array_merge($result,$mp);
                }
            }
            //生成路由文件
            file_put_contents($this->project_folder."/request_route",'<?php return '.var_export($result,1).';');
        }

      然后我来生成路由,把刚才生成所有方法的RequestMapping生成到项目目录下,取个名字叫做request_route.


    知识点:

    反射:1、ReflectionClass :对“类”进行反射,并获取相关信息。

    2、学习获取类“注释”的方法

    $f = new ReflectionClass(类名);

    $doc = $f->getDocComment();  //获取注释

    echo $doc   

    3、get_declared_classes()

    4、__class__ PHP魔力变量 可以获取当前类名

  • 相关阅读:
    核心编程笔记8——用户模式下的线程同步
    核心编程随笔7——线程调度和优先级
    深入浅出mfc随笔——MFc程序的生死因果
    opengl
    核心编程6——线程
    深入浅出mfc学习笔记——六大关键技术之仿真_运行时和动态创建
    深入浅出mfc学习笔记——六大关键技术仿真_Persistence(永久保存)
    Gdi+编程
    深入浅出mfc学习笔记1
    file open等待事件
  • 原文地址:https://www.cnblogs.com/xz1024/p/5864979.html
Copyright © 2020-2023  润新知