zoukankan      html  css  js  c++  java
  • 简化日常工作之三:自己写一个CI脚手架

    程序员是诗人,应该写一些有思想意义的code,而不是每天重复造轮子,写一些低成本的业务逻辑。

                                      ---------------------------------一个脚本仔的心声

    由于目前公司使用CI框架,也遇到过需要大量新建controller,model等的新需求情况,我就在想是否能把一些公用的代码通过批量初始化成文件,减少不必要的重复书写。趁着阶段性上线间隙,我开始写这个基于命令脚本方式的自动化脚手架。基于CI,但是思想是适合任何不带官方脚手架功能的项目。(例如yii有官方的gii,cakephp也有cake命令)

    首先,我要批量生成的文件类型分为三种:controller,model,helper.

    其中controller类文件,除了自动加载同名model外,还自带curd的操作函数定义。而model则预先写进findById函数和具体实现。关于模板的导入,我本来想单独写一个文件来装,然后通过一些字符串替换达到变量赋值,后来觉得有点麻烦,改用heredoc来进行字符串拼接成完整自定义模板。该脚手架项目目录结构如下:

    controllers,helpers,models文件夹分别存放对应生成的文件。

    其中creater.php内容如下:

    <?php
    
    /**
    *  自动化生成代码框架的工具类
    **/
    
    require './config/template.php';
    
    class Creater 
    {
        
        protected $controllers = array();  // 控制器数组
    
        protected $template = null;
    
        protected $models = array();       // 模型数组
    
        protected $helpers = array();     // 组件数组
    
        protected $configs = array();
    
    
        public function __construct()
        {
             require './config/conf.php'; // 加载配置
            $this->configs = $config;
        }
        /**
         * 根据名称和模块生成默认模板内容的控制器
         * 
         * @param  string $controllerStrs
         * @return string
         */
        public function controller($controllerStrs)
        {
            $this->_createFile('controller', $controllerStrs);
        }
    
        /**
         * 根据名称和模块生成默认模板内容的model
         * 
         * @param  string $modelStrs
         * @return string
         */
        public function model($modelStrs)
        {
            $this->_createFile('model', $modelStrs);
        }
    
        /**
         * 根据名称和模块生成默认模板内容的helper
         * 
         * @param  string $helperStrs
         * @return string
         */
        public function helper($helperStrs)
        {
            $this->_createFile('helper', $helperStrs);
        }
    
        /**
         * 将缩写命令补全为完整命令并执行
         * 
         * @param  array $params
         * @return string
         */
        public function alia(array $params)
        {
            $operation = '';
            switch ($params['opt']) {
                case 'c':
                    $operation = 'controller';
                    break;
                case 'm':
                    $operation = 'model';
                    break;
                case 'h':
                    $operation = 'helper';
                    break;
                
                default:
                    exit('error operation !');
                    break;
            }
    
            $this->$operation($params['contents']);
        } 
    
        /**
         * 创建文件
         *
         * @param string $typeName 文件类型
         * @param string $string 文件名字符串,多个以逗号分隔
         * @author freephp
         */
        private function _createFile($typeName, $string){
            $typeField = $typeName . 's';
            $this->$typeField = explode(',', $string);
            if (empty($this->$typeField)) exit("no $typeName's name enter, please check your input!");
            $template = new Template(array('type' => $typeName, 'isNormal' => true));
     
    
            foreach ($this->$typeField as $k => $v) {
    
                $template->className = $v;
    
                if (strstr($v, '/')) {
                    $this->__splitDirsAndFile();
                }
    
                $contents = $template->loadFile();
                
                $filePath = $this->configs[$typeName . 'Path'] . '/' . strtolower($v) . $this->_getFileTail($typeName);
    
                if(!file_exists($filePath)) {
                    $this->_writeFile($filePath, $contents);
                    echo 'success write it!' , "
    ";
                } else {
                    $this->_writeFile($filePath, $contents);
                    print_r('The  ' . $typeName . ' ' . $v . ' has existed,  created again!');
                }
            }
        }
    
        /**
         * 写入文件
         *
         * @param string $filePath 文件地址
         * @param string $contents 文件内容
         * @author freephp
         */
        private function _writeFile($filePath, $contents)
        {
            $fp = fopen($filePath, 'w');
            fputs($fp, $contents);
            fclose($fp);
    
        }
    
        /**
         * 获取文件后缀
         * 
         * @param  string $typeName 文件类型
         * @return string
         */
        private function _getFileTail($typeName) {
            $tail = '.php';
            if ($typeName == 'model') $tail = '_model.php';
            if ($typeName == 'helper') $tail = '_helper.php';
    
            return $tail;
        }
    
        private function __splitDirsAndFile() {
            $path = substr($v, 0, strripos(strtolower($v), '/'));
    
            $toCreatePath = $this->configs[$typeName . 'Path'] . '/' . $path;
            if (!is_dir($toCreatePath)) {
                mkdir($toCreatePath, 0777, true);
            }
    
            $template->className = str_replace($path .'/', '', $v);
        }
    }
    
    /*
        采用脚本方式
    
        生成controller文件
        php creater.php controller game,news,product or php creater.php c game.product
    
        or php creater.php controller game2015/game,news,product
    */
    if (count($argv) < 1) {
        return;
    }
    
    $action = trim($argv[1]);
    $param = trim($argv[2]);
    
    $creater = new Creater();
    
    if (strlen($action) == 1) {
        $creater->alia(['opt' => $action, 'contents' => $param]);
    } else {
        $creater->$action($params);
    }

    不仅可以以逗号分隔方式批量生成代码文件,还可以以/分隔目录和文件,连带目录结构去生成。比如:

    php creater.php controller game/gameClick,ad/adClick,hots/hotClick 

    那么会创建出controllers/game/gameClick.php,

          controllers/ad/adClick.php,

          controllers/hots/hotClick.php

    其中由代码可见,为了方便命令行输入,有alia函数去把缩写命令给补全,如:

    php creater.php c game # => php creater.php controller game

    最后贴出我这个脚手架小工具的github地址:https://github.com/freephp2015/autoCreater   (已有bug修复,新增--help功能)

    欢迎沟通交流。代码要越写越少,做一个lazy man吧。

  • 相关阅读:
    Permutation Sequence
    Sqrt(x)
    Search in Rotated Sorted Array ||
    [STL]list的erase正确与错误用法
    一个支持Git应用编程开发的第三方库(API)
    VC++生成full dump文件
    Maven构建C++工程的插件-NAR
    VC++ Watch窗口查看指针指向的数组
    Android SDK更新失败的解决方法
    ADT20新建项目Android Support library not installed问题
  • 原文地址:https://www.cnblogs.com/freephp/p/5283239.html
Copyright © 2011-2022 走看看