233 lumen 自定义console命令

15 篇文章 0 订阅
本文介绍如何在Lumen框架中自定义Console命令,以简化Repository的创建过程。通过定义命令,可以自动在指定目录下生成Repository文件,并根据需求注入model和创建相应方法。参照Laravel的实现,结合Lumen的特点,完成命令注册和模板定义,最终实现方便快捷的命令行操作。
摘要由CSDN通过智能技术生成

最近用 lumen 写服务端api ,因为我在 model 和 controller 之间加了一个抽象层(repository),所以需要频繁新建不同的 repository,能不能自己定义个 php artisan make:repository命令来帮助我自行创建呢?

需求

自动在 App\Repository下新建新的 XxxRepository.php文件,同时可以实现以下功能

  • 可以指定use的 model
  • 自动创建index(),getOne()等方法

最后的指令应该是形如php artisan make:repository XxxRepository --model=Xxx

查看laravel 的实现方式

namespace Illuminate\Foundation\Console\ModelMakeCommand,这里有现成的MakeModel例子:

  • $name属性指定了 command 名称
  • getStub()方法返回 文件模板 的绝对路径
  • getDefaultNamespace()返回默认命令空间
  • getOptions()获取参数
  • fire()方法执行指令逻辑

新建command

lumen 没有make command,于是手动在app\repository\Commands下新建文件MakeRepository.php:

namespace App\Console\Commands;

use Illuminate\Console\Command;

class MakeRepository extends Command {
    protected $signature = 'make:repository {repository}';
    protected $description = 'make a new repository.';
    public function __construct()
    {
        parent::__construct();
    }
    public function handle()
    {
        echo "make a new repository!\n";
    }
}

并在App\Console\Kernel中注册,修改$commands

protected $commands = [
    \App\Console\Commands\MakeRepository::class,
];

新建stub

app/Console/Commands下新建stubs文件夹,并在它里面新建repository.stub
代码

<?php
namespace App\Repositorys;

use App\Models\$model_name;

class $class_name extends Repository{

    public static function getAll(){

    }
}

修改MakeRepository

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Support\Composer;

class MakeRepository extends Command {

    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    // protected $signature = 'make:repository';
    protected $signature = 'make:repository {repository} {--model=}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'make a new repository.';

    /**
     * @param mixed */
    protected $type = 'Repository';

    public function __construct(Filesystem $filesystem, Composer $composer) {
        parent::__construct();

        $this->files    = $filesystem;
        $this->composer = $composer;
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle(){
        $argument = $this->argument('repository');
        $option   = $this->option('model');

        //自动生成RepositoryInterface和Repository文件
        $this->writeRepository($argument, $option);
        //重新生成autoload.php文件
        $this->composer->dumpAutoloads();
    }

    private function writeRepository($repository, $model){
        if($this->createRepository($repository, $model)){
            //若生成成功,则输出信息
            $this->info('Success to make a '.ucfirst($repository).' Repository');
        }
    }

    private function createRepository($repository, $model) {
        // getter/setter 赋予成员变量值
        $this->setRepository($repository);
        $this->setModel($model);
        // 创建文件存放路径, Repository放在app/Repositorys里
        $this->createDirectory();
        // 生成两个文件
        return $this->createClass();
    }

    private function createClass() {
        //渲染模板文件,替换模板文件中变量值
        $template = $this->templateStub();
        return $this->files->put($this->getPath(), $template);
    }

    private function getPath() {
        // 两个模板文件,对应的两个路径
        $path = $this->getDirectory().DIRECTORY_SEPARATOR.$this->getRepositoryName().'.php';
        return $path;
    }

    private function getRepositoryName() {
        // 根据输入的repository变量参数,是否需要加上'Repository'
        $repositoryName = $this->getRepository();
        if((strlen($repositoryName) <= strlen('Repository')) || strrpos($repositoryName, 'Repository', -11)){
            $repositoryName .= 'Repository';
        }
        return $repositoryName;
    }

    public function setRepository($repository) {
        $this->repository = $repository;
    }

    public function getRepository() {
        return $this->repository;
    }

    public function setModel($model) {
        $this->model = $model;
    }

    private function templateStub() {
        // 获取模板文件
        $stub = $this->getStub();

        // 获取需要替换的模板文件中变量
        $templateData = $this->getTemplateData();

        return $this->getRenderStub($templateData, $stub);
    }

    private function getTemplateData(){
        return [
            'class_name' => $this->getRepositoryName(),
            'model_name' => $this->getModelName(),
        ];
    }

    private function getModelName() {
        $modelName = $this->getModel();
        if(isset($modelName) && !empty($modelName)){
            $modelName = ucfirst($modelName);
        }else{
            // 若option选项没写,则根据repository来生成Model Name
            $modelName = $this->getModelFromRepository();
        }

        return $modelName;
    }

    private function getModelFromRepository() {
        $repository = strtolower($this->getRepository());
        $repository = str_replace('repository', '', $repository);
        return ucfirst($repository);
    }

    private function getRenderStub($templateData, $stub) {
        foreach ($templateData as $search => $replace) {
            $stub = str_replace('$'.$search, $replace, $stub);
        }

        return $stub;
    }

    private function createDirectory() {
        $directory = $this->getDirectory();
        //检查路径是否存在,不存在创建一个,并赋予775权限
        if(! $this->files->isDirectory($directory)){
            return $this->files->makeDirectory($directory, 0755, true);
        }
    }

    private function getDirectory() {
        return dirname(dirname(__DIR__)).'/Repositorys';
    }

    /**
     * @return mixed
     */
    public function getModel(){
        return $this->model;
    }

    /**
     * Get the stub file for the generator.
     *
     * @return string
     */
    protected function getStub() {
        return $this->files->get(__DIR__.'/stubs/repository.stub');
    }

    /**
     * Get the default namespace for the class.
     *
     * @param  string  $rootNamespace
     * @return string
     */
    protected function getDefaultNamespace($rootNamespace)
    {
        return $rootNamespace;
    }
}

测试

$ php artisan make:repository TestRepository --model=TestModel
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值