继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

给thinkphp5增加同时生成model和附属服务文件功能

幕布斯6054654
关注TA
已关注
手记 1135
粉丝 218
获赞 1009

使用Eloquent ORM是tp官方最为推荐的,不过每次手动复制文件非常麻烦,而虽然框架提供生成空文件的脚本命令,不过在具体定制项目里意义不大,而且为了规范和减少耦合,需要在model和controller之间在加入一个过渡层,这也是tp官方以及其它包括lavarel在内主流框架开发者的看法,项目大中间文件需要做成接口模式以规范开发,如果项目中等或者小,则无需这么麻烦,直接生成一个service服务继承指定的model就可以了。
1.先准备model模板
因为model直接和表映射,因此可以通过传表名直接生成,按照框架规划,直接把命令放在make模块下

 <?phpnamespace {%namespace%};use think\Model;class {%className%} extends Model
{    protected $table = '{%tablename%}';
}

2.在准备文件生成类

<?php namespace think\console\command\make;use think\console\command\Make;use think\App;use think\Config;use think\console\Command;use think\console\Input;use think\console\input\Argument;use think\console\Output;/**
 * 生成model和service
 */class Ms extends Make{   const SERVICEERROR = '<error>this service already exists!</error>';    const MODELERROR = '<error>this model already exists!</error>';    const SERVICESUCCSESS = '<info>this service already successfully!</info>';    const MODELSUCCSESS = '<info>this model already successfully!</info>';    protected $tablename = '';    /**
     * 命令备注
     * Typecho Blog Platform
     * @copyright [copyright]
     * @license   [license]
     * @version   [version]
     * @return    [type]      [description]
     */
    protected function configure()
    {        parent::configure();        $this->setName('make:ms')
            ->setDescription('Create a new model class and service class');
    }    /**
     * 生成文件
     * Typecho Blog Platform
     * @copyright [copyright]
     * @license   [license]
     * @version   [version]
     * @param     Input       $input  [description]
     * @param     Output      $output [description]
     * @return    [type]              [description]
     */
    protected function execute(Input $input, Output $output)
    {
        $name = trim($input->getArgument('name'));        $this->tablename = self::get_name($name);//保存数据表名称
        $this->namespace = App::$namespace.'\\'.str_replace($this->tablename,'',str_replace('/','\\',$name));//设置命名空间根路径
        $this->file = str_replace($this->tablename,'',$name);        // $classname = $this->getClassName($name);
        $classname = self::setHump($this->tablename);//转为驼峰模式
        $this->input = $input;        $this->output = $output;        $this->createModel($classname);//生成model

        $this->createService($classname);//生成service
    }    /**
     * 生成model文件
     * Typecho Blog Platform
     * @copyright [copyright]
     * @license   [license]
     * @version   [version]
     * @param     [type]      $classname [类名]
     */
    protected function createModel($classname)
    {        if (!preg_match("/(Model|model)+$/",$classname)) {
            $classname .= "Model";            $this->serviceusespance = $this->namespace.'model\\'.$classname;
        }
        
        $pathname = APP_PATH.$this->file.'model/'.$classname.'.php';        if (is_file($pathname)) {            $this->output->writeln(static::MODELERROR);            return false;
        }        if (!is_dir(dirname($pathname))) {
            mkdir(strtolower(dirname($pathname)), 0755, true);
        }

        file_put_contents($pathname, $this->buildClassModel($classname));        $this->output->writeln(static::MODELSUCCSESS);
    }    /**
     * 生成service
     * Typecho Blog Platform
     * @copyright [copyright]
     * @license   [license]
     * @version   [version]
     * @param     [type]      $classname [类名]
     */
    protected function createService($classname)
    {        if (!preg_match("/(Service|service)+$/",$classname)) {
            $classname .= "Service";
        }
        $pathname = APP_PATH.$this->file.'service/'.$classname.'.php';        if (is_file($pathname)) {            $this->output->writeln(static::SERVICEERROR);            return false;
        }        if (!is_dir(dirname($pathname))) {
            mkdir(strtolower(dirname($pathname)), 0755, true);
        }
        file_put_contents($pathname, $this->buildClassService($classname));        $this->output->writeln(static::SERVICESUCCSESS);
    }    /**
     * 读取model模板
     * Typecho Blog Platform
     * @copyright [copyright]
     * @license   [license]
     * @version   [version]
     */
    protected function getStub()
    {        return __DIR__ . '/stubs/model2.stub';
    }    /**
     * 读取service模板
     * Typecho Blog Platform
     * @copyright [copyright]
     * @license   [license]
     * @version   [version]
     */
    protected function getServiceStub()
    {        return __DIR__ . '/stubs/service.stub';
    }    /**
     * 生成model
     */
    protected function buildClassModel($name)
    {
        $stub = file_get_contents($this->getStub());

        $namespace = $this->namespace.'model';        return str_replace(['{%className%}', '{%namespace%}', '{%tablename%}'], [
            $name,
            $namespace,            $this->tablename
        ], $stub);
        
    }    /**
     * 生成service专属,生成model的时候顺便生成附属service服务
     */
    protected function buildClassService($name)
    {
        $stub = file_get_contents($this->getServiceStub());

        $namespace = $this->namespace.'service';        
        return str_replace(['{%className%}', '{%namespace%}', '{%usenamespace%}'], [
            $name,
            $namespace,            $this->serviceusespance
        ], $stub);
        
    }    //将字符串转为驼峰模式
    private static function setHump($str)
    {        if (false === stripos($str,'_')) {
            $str = ucfirst($str);
        } else {
            $strList = explode('_',$str);
            $newStr = '';            foreach ($strList as $value) {
                $newStr .= ucfirst($value);
            }
            $str  = $newStr;
        }        return $str;
    }    /**
     * 截取文件名称
     */
    private static function get_name($str)
    {        return substr($str,strrpos($str,'/')+1,(strlen($str)-strrpos($str,'/')));
    }
}

3.在配置命令调用,加上生成ms的命令

private static $defaultCommands = [        "think\\console\\command\\Help",        "think\\console\\command\\Lists",        "think\\console\\command\\Build",        "think\\console\\command\\Clear",        "think\\console\\command\\make\\Ms",        "think\\console\\command\\make\\Controller",        "think\\console\\command\\make\\Model",        "think\\console\\command\\optimize\\Autoload",        "think\\console\\command\\optimize\\Config",        "think\\console\\command\\optimize\\Route",        "think\\console\\command\\optimize\\Schema",
    ];

这样就可以使用这个行命令了


webp

TIM截图20181207083916.png



作者:日落之国
链接:https://www.jianshu.com/p/c5e1b1a33b48


打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP