• php 魔鬼训练


    环境配置

    找到自己的【系统命令行】目录:bin

    /usr/bin    #mac系统
    /bin        #ubuntu系统 

    再找到Php的编译器,这个根据你的安装路径来判断,mac默认的路径如下

    cd /usr/bin #mac系统默认路径
    cd /usr/local/php/bin/  #我的ubuntu中php的安装路径
    ./php -v #测试

    新建php文件命名为lee(注意,#! 后面的参数是你的php编译器路径,这里我使用了mac自带的php编译器。这样一来,无论将文件放置在哪里,都可以用php编译器来运行该文件)

    #! /usr/bin/php
    <?php 
      echo "I am god".PHP_EOL;
    ?>

    将lee复制到【系统命令行】目录中

    sudo cp ./lee /usr/bin  #mac系统的Bin的路径

    这样一来,无论在什么路径下载命令行中输入:lee  都可以输出“I am god”

    完成了自己的命令行

    正式开始


     

    demo1

    知识点:

    && 这里并不是并且的意思,而是表达式如果成立,则执行后面的语句 
    PHP_EOL 这里是换行的意思。因为Linux和window换行的语法不一样【
    和
    】,所以使用这种写法统一
    #! /usr/bin/php
    <?php
      echo "I am god".PHP_EOL;
      $result = '';
      if($argc > 1)  //执行lee时,自己算是一个参数,所以如果有第二个参数就一定是大1的
      {
        '-v' == $argv[1] && $result = 'god version is 1.0';
      }
    
      $result != '' && exit($result.PHP_EOL);
    ?>

    demo2:

    新建类库lee_class
    知识点:
    fgets(STDIN) 获取用户键盘输入
    <?php 
    class lee
    {
        static $VERSION = 'god version is 1.1';
        static $project_name = '';  //项目名称
        static $project_author = ''; //项目作者
    
        static function init()
        {
            echo "input your project name : ";
            self::$project_name = fgets(STDIN);
    
            echo "input your author name : ";
            self::$project_author = fgets(STDIN);
    
            return 'lee init complete';
        }
    }
    ?>

    修改lee

    #! /usr/bin/php
    <?php 
      require('lee_func');
      require('lee_class');
      $result = '';
      if($argc > 1)  
      {
        '-v' == $argv[1] && $result = lee::$VERSION;
        'init' == $argv[1] && $result = lee::init();  
      }
      $result != '' && exit($result.PHP_EOL);
      echo 'I am god'.PHP_EOL;
    ?>

    demo3:

    修改lee_class

    知识点:__callStatic 未定义的静态函数调用时,会触发该函数

    <?php 
    require('lee_config');
    class lee
    {
        static $v = 'god version is 1.2';
        static function init()
        {
            $lee_config = new lee_config();
    
            echo "input your project name : ";
            $lee_config->project_name = fgets(STDIN);//项目名称
    
            echo "input your author name : ";
            $lee_config->project_author = fgets(STDIN);//项目作者
    
            $json = json_encode($lee_config);
    
            return file_put_contents(getcwd().'/god.json',$json).' of bytes is written'.PHP_EOL.'god config is created';
        }
    
        //未定义的静态函数调用时,会触发该函数
        static function __callStatic($m,$static_func)
        {
            exit("static function '{$m}' is not define".PHP_EOL);
        }
    }
    ?>

    添加类lee_config

    <?php 
    
    class lee_config
    {
        //项目名称
        public $project_name;    
    
        //项目作者
        public $project_author;    
    }
    
    ?>

    修改lee (添加了php版本的“反射”来动态获取用户输入并且转换为属性或者方法)

    知识点:利用php版本的“反射”来动态获取用户输入并且转换为属性或者方法

    #! /usr/bin/php
    <?php 
      require('lee_class');
      $result = '';
      if($argc > 1)  
      {
        $p = $argv[1];
        if(substr($p, 0,1) == '-')
        {
            //有'-'说明是属性,利用php版本的“反射”获取属性,当然还要判断一下属性是否存在
            $p = substr($p,1);
            //由于属性的调用格式是$name,所以这里有两个$,
            $result = isset(lee::$$p)?lee::$$p:"command -{$p} is undefind";
        }
        else
        {
            //否则就是方法或者事件,利用php版本的“反射”获取方法,当然还要判断一下方法是否存在
            $result = lee::$p();
        }
      }
      $result != '' && exit($result.PHP_EOL);
    ?>

    demo4:生成项目雏形

    修改lee_class

    <?php 
    require('lee_config');
    class lee
    {
        static $v = 'god version is 1.2';
        static function init()
        {
            $lee_config = new lee_config();
    
            echo "input your project name : ";
            $lee_config->project_name = fgets(STDIN);//项目名称
    
            echo "input your author name : ";
            $lee_config->project_author = fgets(STDIN);//项目作者
    
            $json = json_encode($lee_config);
    
            return file_put_contents(getcwd().'/lee.json',$json).' of bytes is written'.PHP_EOL.'god config is created';
        }
    
        static function config()
        {
            $json = file_get_contents(getcwd().'/lee.json');
            $obj = json_decode($json);
            $result = '';
            foreach ($obj as $key => $value) {
                $result .= $key.' = '.$value.PHP_EOL;
            }
            return $result;
        }
    
        static function make()
        {
            $json = file_get_contents(getcwd().'/lee.json');
            $obj = json_decode($json);
            !file_exists(getcwd().'/'.$obj->project_name) && mkdir(getcwd().'/'.$obj->project_name);
        }
    
        //未定义的静态函数调用时,会触发该函数
        static function __callStatic($m,$static_func)
        {
            exit("static function '{$m}' is not define".PHP_EOL);
        }
    }
    ?>

    demo5:加强骨架

    添加类lee_frame,专门管理骨架

    <?php 
    class lee_frame
    {
        public $folder = "";    //项目文件夹
        public $entry = "";        //入口文件
        function __construct($name)
        {
            $this->folder = getcwd().'/'.$name;
            $this->entry = $this->folder.'/index.php';
        }
    
        function run()
        {
            !file_exists($this->folder) && mkdir($this->folder);  //创建项目文件夹
            !file_exists($this->entry) && file_put_contents($this->entry,''); //创建项目入口
        }
    }
    ?>

    优化了config的名称,修改一下lee_class和lee_config

    <?php 
    require('lee_config');
    class lee
    {
        static $v = 'god version is 1.2';
        static function init()
        {
            $lee_config = new lee_config();
    
            echo "input your project name : ";
            $lee_config->name = fgets(STDIN);//项目名称
    
            echo "input your author name : ";
            $lee_config->author = fgets(STDIN);//项目作者
    
            $json = json_encode($lee_config);
    
            return file_put_contents(getcwd().'/lee.json',$json).' of bytes is written'.PHP_EOL.'god config is created';
        }
    
        static function config()
        {
            $json = file_get_contents(getcwd().'/lee.json');
            $obj = json_decode($json);
            $result = '';
            foreach ($obj as $key => $value) {
                $result .= $key.' = '.$value.PHP_EOL;
            }
            return $result;
        }
    
        static function make()
        {
            $json = file_get_contents(getcwd().'/lee.json');
            $obj = json_decode($json);
            require('lee_frame');
            $lee_frame = new lee_frame($obj->name);
            $lee_frame->run();
        }
    
        //未定义的静态函数调用时,会触发该函数
        static function __callStatic($m,$static_func)
        {
            exit("static function '{$m}' is not define".PHP_EOL);
        }
    }
    ?>

    简化了名称lee_config

    <?php 
    
    class lee_config
    {
        //项目名称
        public $name;    
    
        //项目作者
        public $author;    
    }
    
    ?>

    demo6:继续加强骨架

    将lee_frame搬家到更深的目录,同时也是为了优化框架和学习命名空间

    coreframelee_frame

    知识点:命名空间,在不同的命名空间下可以定义同名的类。但是注意有个致命,这样一来所有new class的类实例化,默认都会加上命名空间,最简单的解决方法就是:new class  

    <?php 
    namespace coreframe;
    class lee_frame
    {
        public $folder = "";    //项目文件夹
        public $entry = "";        //入口文件
        function __construct($name)
        {
            $this->folder = getcwd().'/'.$name;
            $this->entry = $this->folder.'/index.php';
        }
    
        function run()
        {
            !file_exists($this->folder) && mkdir($this->folder);  //创建项目文件夹
            !file_exists($this->entry) && file_put_contents($this->entry,''); //创建项目入口
        }
    }
    ?>

    修改lee_class

    知识点:1、__autoload  如果new未找到的类,会触发这个函数

        2、use coreframelee_frame 加载命名空间,这样一来所有lee_frame的类,都只会加载命名空间为coreframe的类了

    <?php 
    require('lee_config');
    use coreframelee_frame;
    //如果new未找到的类,会触发这个函数
    function __autoload($className)
    {
        $className = str_replace('\', '/', $className);
        require($className);
    }
    
    class lee
    {
        static $v = 'god version is 1.2';
        static function init()
        {
            $lee_config = new lee_config();
    
            echo "input your project name : ";
            $lee_config->name = str_replace("
    ","",fgets(STDIN));  //项目名称
    
            echo "input your author name : ";
            $lee_config->author = str_replace("
    ","",fgets(STDIN)); //项目作者
    
            $json = json_encode($lee_config);
    
            return file_put_contents(getcwd().'/lee.json',$json).' of bytes is written'.PHP_EOL.'god config is created';
        }
    
        static function config()
        {
            $json = file_get_contents(getcwd().'/lee.json');
            $obj = json_decode($json);
            $result = '';
            foreach ($obj as $key => $value) {
                $result .= $key.' = '.$value.PHP_EOL;
            }
            return $result;
        }
    
        static function make()
        {
            $json = file_get_contents(getcwd().'/lee.json');
            $obj = json_decode($json);
            $lee_frame = new lee_frame($obj->name);
            $lee_frame->run();
        }
    
        //未定义的静态函数调用时,会触发该函数
        static function __callStatic($m,$static_func)
        {
            exit("static function '{$m}' is not define".PHP_EOL);
        }
    }
    ?>

    demo7:渲染Php模板

    修改lee_class

    知识点:将变量赋值给类中的属性,在php中,哪怕属性没有在类中初始化/定义,那么在赋值的时候也可以当场定义的。

    <?php 
    require('lee_config');
    use coreframelee_frame;
    //如果new未找到的类,会触发这个函数
    function __autoload($className)
    {
        $className = str_replace('\', '/', $className);
        require($className);
    }
    
    class lee
    {
        static $v = 'god version is 1.2';
        static function init()
        {
            $lee_config = new lee_config();
    
            echo "input your project name : ";
            $lee_config->name = str_replace("
    ","",fgets(STDIN));  //项目名称
    
            echo "input your author name : ";
            $lee_config->author = str_replace("
    ","",fgets(STDIN)); //项目作者
    
            $json = json_encode($lee_config);
    
            return file_put_contents(getcwd().'/lee.json',$json).' of bytes is written'.PHP_EOL.'god config is created';
        }
    
        static function config()
        {
            $json = file_get_contents(getcwd().'/lee.json');
            $obj = json_decode($json);
            $result = '';
            foreach ($obj as $key => $value) {
                $result .= $key.' = '.$value.PHP_EOL;
            }
            return $result;
        }
    
        static function make()
        {
            $json = file_get_contents(getcwd().'/lee.json');
            $obj = json_decode($json);
            $lee_frame = new lee_frame($obj->name);
            $lee_frame->name = $obj->name;     //将项目名传入类中
            $lee_frame->author = $obj->author; //将作者名传入类中
            $lee_frame->run();
        }
    
        //未定义的静态函数调用时,会触发该函数
        static function __callStatic($m,$static_func)
        {
            exit("static function '{$m}' is not define".PHP_EOL);
        }
    }
    ?>

    新增index.tpl

    知识点:奇思淫巧

    <?php echo '<?php'.PHP_EOL; ?>
    /**
     * name:<?php echo $name; ?> 
     * User: <?php echo $author.PHP_EOL;; ?>
     * Date: <?php ini_set('date.timezone','Asia/Shanghai'); echo date('Y-m-d') ?> 
     */
     echo "hello world";

    修改lee_frame

    知识点:extract(get_object_vars($this));  //这个东西比较复杂,首先将指定的类中的属性化为一个数组,然后extract解析数组

    <?php 
    namespace coreframe;
    class lee_frame
    {
        public $folder = "";    //项目文件夹
        public $entry = "";        //入口文件
        function __construct($name)
        {
            $this->folder = getcwd().'/'.$name;
            $this->entry = $this->folder.'/index.php';
        }
    
        function run()
        {
            //创建项目文件夹(如果不存在)
            !file_exists($this->folder) && mkdir($this->folder);  
            //打开缓存区,不让内容输出到界面去
            ob_start();
            //这个东西比较复杂,首先将指定的类中的属性化为一个数组,然后extract解析数组
            extract(get_object_vars($this)); 
            //获取模板内容(需要好好研究学习一下模板的小技巧)
            include dirname(__FILE__).'/tpl/index.tpl';
            //获取缓冲区的内容
            $contents = ob_get_contents();
            //关闭并且清除缓冲区
            ob_end_clean();
            //创建项目入口(覆盖)
            file_put_contents($this->entry,$contents); 
        }
    }
    ?>

    demo8 : 开启php内置的服务器

    #套路
    php -S localhost:9900 -t 目录
    
    #demo
    /usr/bin/php -S localhost:9900 -t /Users/apple/Desktop/lee/test

    demo9

    修改lee_frame

    知识点:1、反射

        2、get_defined_functions   获取所有已定义的变量

        3、get_defined_functions   获取所有函数(包含内置和自定义)

        4、文件操作 scandir 

    <?php 
    namespace coreframe;
    class lee_frame
    {
        public $folder = "";       //项目文件夹
        public $entry = "";        //入口文件
        function __construct($name)
        {
            $this->folder = getcwd().'/'.$name;
            $this->entry = $this->folder.'/index.php';
        }
    
        function compile()
        {
            //获取项目/code下所有的文件
            $_files = scandir($this->folder.'/code');
            foreach($_files as $_file)
            {
                //匹配如aaa.var.php的文件
                if(preg_match("/w+.var|func.php$/i", $_file))
                {
                    require($this->folder.'/code/'.$_file);
                }
            }
    
            unset($_files);  //摧毁变量,仅仅是为了下面的get_defined_vars
            unset($_file);   //摧毁变量,仅仅是为了下面的get_defined_vars
            
            $var_results = var_export(get_defined_vars(),true);
            $result = '<?php'.PHP_EOL
                             ."extract({$var_results})";
    
    
            file_put_contents($this->folder.'/vars', $result);
    
    
            //获取所有自定义函数                 
            $func_results = get_defined_functions()['user']; 
    
            //拼接的函数字符串
            $func_str = '<?php '.PHP_EOL
                                ."/*".PHP_EOL
                                ."* compile by lee {date(Y-m-d h:i:s)}".PHP_EOL
                                .'*/'.PHP_EOL;
    
            foreach ($func_results as $func) 
            {
                //反射
                $f = new ReflectionFunction($func);
                $start=$f->getStartLine();  //函数所在文件位置的起始行
                $end=$f->getEndLine();      //函数所在文件位置的结束行
                $file_arr = file($f->getFileName()); //根据路径获取所有的内容,根据内容的换行作为数组的索引
                $func_arr = array_slice($file_arr, $start - 1,$end - $start + 1); //根据上面的数组,返回纯函数的行内容
                $func_str .= implode($func_arr); //获取函数纯字符串
            }
    
            file_put_contents($this->folder.'/functions', $func_str);
    
        }
    
        function run()
        {
            //创建项目文件夹(如果不存在)
            !file_exists($this->folder) && mkdir($this->folder);  
            //打开缓存区,不让内容输出到界面去
            ob_start();
            //这个东西比较复杂,首先将指定的类中的属性化为一个数组,然后extract解析数组
            extract(get_object_vars($this)); 
            //获取模板内容(需要好好研究学习一下模板的小技巧)
            include dirname(__FILE__).'/tpl/index.tpl';
            //获取缓冲区的内容
            $contents = ob_get_contents();
            //关闭并且清除缓冲区
            ob_end_clean();
            //创建项目入口(覆盖)
            file_put_contents($this->entry,$contents); 
        }
    
    
    }
    ?>

    demo10

    添加lee_mvc

    <?php 
    
    namespace coreframe;
    class lee_mvc
    {
        public $classNmae = '';  //类名
        public $classComment = '';  //类的注释
        public $classMethods = array(); //类中所有的方法
    
        function __construct($cname)
        {
            $this->classNmae = $cname;
            //类反射
            $f = new ReflectionClass($cname);
            //获取类的注释
            $this->classComment = $f->getDocComment();    
            //获取类中所有的方法,返回的数组中值,实际上是反射(函数)
            $this->classMethods = $f->getMethods();
        }
    
        function IsController()
        {
            return preg_match('/@Controller/', $this->classComment);
        }
    
        function getRequestMapping()
        {
            $arr1 = array();
            foreach ($this->classMethods as $value) {
                //获取类方法的注释
                $arr2 = $this->getRequestMappingResult($value);
                if($arr2)
                {
                    $arr1 = array_merge($arr1,$arr2);
                }
            }
            return $arr1;
        }
    
        function getRequestMappingResult($medhod)
        {
            //@RequestMapping("/getme",Method=GET);
            if(preg_match('/@RequestMapping("(.{2,50})",Method=(w{3,8}));/', $medhod->getDocComment(),$result))
            {
                $Method = $medhod->getName();   //方法名
                $RequestUrl = $result[1];        //url地址
                $RequestMethod = $result[2];  //post或者get
                return array( 
                        $RequestUrl => array('RequestMethod'=>$RequestMethod,'Class'=>$this->classNmae,'Method'=>$Method)
                );
            }
            return false;
        }
    }

    修改lee_frame

    <?php 
    namespace coreframe;
    use coreframelee_mvc; 
    ini_set('date.timezone','Asia/Shanghai');
    
    class lee_frame
    {
        public $folder = "";       //项目文件夹
        public $entry = "";        //入口文件
        function __construct($name)
        {
            $this->folder = getcwd().'/'.$name;
            $this->entry = $this->folder.'/index.php';
        }
    
        function compile()
        {
            //获取项目/code下所有的文件
            $_files = scandir($this->folder.'/code');
            foreach($_files as $_file)
            {
                //匹配如aaa.var.php的文件
                if(preg_match("/w+.var|func|class.php$/i", $_file))
                {
                    require($this->folder.'/code/'.$_file);
                }
            }
    
            unset($_files);  //摧毁变量,不要污染到自定义的变量,也是为了下面的get_defined_vars
            unset($_file);   //摧毁变量,不要污染到自定义的变量,也是为了下面的get_defined_vars
            
            $var_results = var_export(get_defined_vars(),true);
            $result = '<?php'.PHP_EOL
            ."extract({$var_results});";
    
    
            file_put_contents($this->folder.'/vars', $result);
    
    
            //获取所有自定义函数                 
            $func_results = get_defined_functions()['user']; 
    
            //拼接的函数字符串
            $func_str = "<?php ".PHP_EOL
            ."/*".PHP_EOL
            ."* compile by lee ".date('Y-m-d h:i:s').PHP_EOL
            ."*/".PHP_EOL;
    
            foreach ($func_results as $func) 
            {
                 //反射(函数)
                $f = new ReflectionFunction($func);
                $start=$f->getStartLine();  //函数所在文件位置的起始行
                $end=$f->getEndLine();      //函数所在文件位置的结束行
                $file_arr = file($f->getFileName()); //根据路径获取所有的内容,根据内容的换行作为数组的索引
                $func_arr = array_slice($file_arr, $start - 1,$end - $start + 1); //根据上面的数组,返回纯函数的行内容
                $func_str .= implode($func_arr); //获取函数纯字符串
            }
    
            file_put_contents($this->folder.'/functions', $func_str);
    
    
            //获取项目中所有的类
            $class_Result = get_declared_classes();
            //获取当前类名的键
            $class_key = array_search(__CLASS__, $class_Result);
            //我也不知道为啥排到当前类之后的类就是自定义的类,算了先写再说吧
            $class_Result = array_slice($class_Result, $class_key + 1);
            $arr1 = array();
            foreach ($class_Result as $value) 
            {
              $mvc = new lee_mvc($value);
              if($mvc->IsController())
              {
                    $arr2 = $mvc->getRequestMapping();
                    $arr1 = array_merge($arr1,$arr2);
              }
            }
    
            file_put_contents($this->folder.'/request_route', "<?php ".PHP_EOL." return ".var_export($arr1,true).";");
           
    
        }
    
        function run()
        {
            //创建项目文件夹(如果不存在)
            !file_exists($this->folder) && mkdir($this->folder);  
            //打开缓存区,不让内容输出到界面去
            ob_start();
            //这个东西比较复杂,首先将指定的类中的属性化为一个数组,然后extract解析数组
            extract(get_object_vars($this)); 
            //获取模板内容(需要好好研究学习一下模板的小技巧)
            include dirname(__FILE__).'/tpl/index.tpl';
            //获取缓冲区的内容
            $contents = ob_get_contents();
            //关闭并且清除缓冲区
            ob_end_clean();
            //创建项目入口(覆盖)
            file_put_contents($this->entry,$contents); 
    
            //开启我心爱的小耗子
            echo "lee server is started in 9900".PHP_EOL;
            system('/usr/bin/php -S localhost:9900 -t '.$this->folder);
        }
    
    
    }
    ?>
  • 相关阅读:
    Linux下安装软件遇见的问题汇总
    使用AlarmManager定期执行工作
    android打开文件、保存对话框、创建新文件夹对话框(转载)
    一些算法的整理
    安卓adb调试命令常见的问题
    java下的串口通信-RXTX
    Unity 协程运行时的监控和优化
    Unity3D 协程的介绍和使用
    游戏服务器:到底使用UDP还是TCP
    Unity 可重复随机数
  • 原文地址:https://www.cnblogs.com/CyLee/p/5744678.html
Copyright © 2020-2023  润新知