簡化日常工作之三:自己寫一個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!' , "\r\n";
            } 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吧。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM