作为程序员一定要保持良好的睡眠,才能好编程

laravel-脚手架脚本实现

发布时间:2020-05-07


提前准备:



带有参数的脚本

 protected $signature = 'mq_ps:publish:send

    {--info= : 请输入内容}';



执行时候,需要使用--info

php artisan mq_ps:publish:send --info=asdf


$tableNames = [

['地址表', 'address',],

['用户表', 'user',],

['商品表', 'goods',],

];

$this->table(['名称', '表名称'], $tableNames);


$tables = [

'address',

'user',

'goods'

];

$table = $this->choice('选择一张执行的表?', $tables, '0');


$isExec = $this->confirm('您确认要执行表' . $table . '?', true);

var_export($isExec);


$str = $this->option('info');

echo $str;


这样的输出,比使用print  和 dump 好多啦。





exit;





image.png



config配置项: yz_scaffold.php

return [
    'controller_path' => app_path('Http' . DIRECTORY_SEPARATOR . 'Controllers'),
    'manager_path' => app_path('Managers'),
    'service_path' => app_path('Services'),
    'model_path' => app_path('Models'),
    'validator_path'=>app_path('Validators'),
];



脚手架脚本:

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Str;

class Create extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'create
    {--del_module= : delete module name}
    {--force : Overwrite any existing files}';

    // 带有等号的 可以输入值
    // {--action=create : action-name}  带有默认值
    //不带有等号的,是一个选项

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = '脚手架项目';


    private $connection;

    private $tableName;

    private $className;

    /** @var 项目根目录 */
    private $basePath;

    /** @var 目录分割符号 */
    const DS = DIRECTORY_SEPARATOR;

    private $fileDescription = '';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
        $this->basePath = base_path();
        $this->ds = DIRECTORY_SEPARATOR;
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        //删除
        if ($this->option('del_module')) {
            $this->delModule($this->option('del_module'));
            exit;
        }

        $className = $this->ask('请输入要生成的类名:', '');

        if (empty($className)) {
            $this->warn("要生成的类名不能为空");
            exit;
        }
        $this->className = ucfirst($className);
        $this->question('要生成的类名是:' . $this->className);

        $this->fileDescription = $fileDescription = $this->ask('请简单描述-只支持英文:', '');
        $this->question('描述信息信息是:' . $fileDescription);

        if (empty($fileDescription)) {
            $this->warn("描述不能为空");
            exit;
        }

        $connection = $this->ask('请输入Model关联的连接 Connection:', '');
        if (empty($connection)) {
            $connection = 'mysql';
        }

        $this->connection = $connection;

        $this->info('connection:' . $connection);

        $tableName = $this->ask('请输入类对应的表名(可以为空):', '');

        if (empty($tableName)) {
            $tableName = $className;
        }

        $this->tableName = $tableName = Str::snake($tableName);

        $this->info('Model关联的表是:' . $tableName);

        //创建控制器
        $this->createController();
        $this->createModel();
        $this->createManager();
        $this->createService();
        $this->createRequest();
    }

    private function createController()
    {

        $controllerStub = <<<'TOT'
<?php

namespace --namespace--;

use App\Http\Requests\--controllerName--Request;
use --manageNamespace--\--controllerName--Manager;
/**
 * --fileDescription--
 * Class --controllerName--
 * @package App\Http\Controllers
 * @date --datetime--
 */
class --controllerName--Controller extends ApiController
{

    /**
     *
     * add
     * @param --controllerName--Request $request
     * @return \Illuminate\Http\JsonResponse
     *
     * @date --datetime--
     */
    public function add(--controllerName--Request $request)
    {
        $param = $request->all();
        $result = $this->getManager()->add($param);

        return $this->showJson($result);
    }

    /**
     *
     * update
     * @param --controllerName--Request $request
     * @return \Illuminate\Http\JsonResponse
     *
     * @date --datetime--
     */
    public function update(--controllerName--Request $request)
    {
        $id = $request->input('id');
        $param = $request->except('id');

        $result = $this->getManager()->update($id, $param);

        return $this->showJson($result);
    }

    /**
     *
     * getList
     * @param --controllerName--Request $request
     * @return \Illuminate\Http\JsonResponse
     *
     * @date --datetime--
     */
    public function getList(--controllerName--Request $request)
    {
        $rules = [

        ];

        $data = $request->except(['pageNumber', 'pageSize']);
        $where = $this->where($rules, $this->filterData($data));

        $pageNumber = $request->input('pageNumber', 1);
        $pageSize = $request->input('pageSize', 10);
        $result = $this->getManager()->getList($where, self::LIST_FIELDS, $pageSize, $pageNumber);

        return $this->showJson($result);
    }

    /**
     *
     * del
     * @param --controllerName--Request $request
     * @return \Illuminate\Http\JsonResponse
     *
     * @date --datetime--
     */
    public function del(--controllerName--Request $request)
    {
        $id = $request->input('id');
        $result = $this->getManager()->del($id);

        return $this->showJson($result);
    }

     /**
     *
     * getManager
     * @return --controllerName--Manager
     *
     * @date --datetime--
     */
    public function getManager()
    {
        return new --controllerName--Manager();
    }
}

TOT;
        $controllerPath = config('yz_scaffold.controller_path');
        $controllerPath = app_path() . str_replace(app_path(), '', $controllerPath);

        $currentNameSpace = $this->calculationNameSpace($controllerPath);
        $managerNameSpace = $this->calculationNameSpace(config('yz_scaffold.manager_path'));

        $content = str_replace([
            '--controllerName--',
            '--datetime--',
            '--namespace--',
            '--manageNamespace--',
            '--fileDescription--'
        ],
            [$this->className, date("Y-m-d H:i:s"), $currentNameSpace, $managerNameSpace, $this->fileDescription],
            $controllerStub);

        //判断如果存在,则提醒用户是否覆盖
        $controllerFile = $controllerPath . self::DS . $this->className . 'Controller.php';
        $createFlag = true;

        if (file_exists($controllerFile) && !$this->option('force')) {
            //提示用户是否替换,如果不 则不生成
            $createFlag = $this->confirm($this->className . 'Controller.php' . ' 文件已存在,是否替换');
        }


        if (!$createFlag) {
            return false;
        }
        $fileSize = file_put_contents($controllerFile, $content);

        $this->info($controllerFile . ' 文件创建成功' . $fileSize);
    }

    private function createRequest()
    {

        $validatorStub = <<<'TOT'
<?php

namespace --namespace--;

use App\Components\Core\FormRequest;

/**
 * --fileDescription--
 * Class --validateName--Validator
 * @date --datetime--
 */
class --validateName--Validator extends FormRequest
{
    protected $update = [

    ];

    protected $del = [

    ];

}

TOT;
        $validatorPath = config('yz_scaffold.validator_path');
        $validatorPath = app_path() . str_replace(app_path(), '', $validatorPath);

        $currentNameSpace = $this->calculationNameSpace($validatorPath);

        $content = str_replace([
            '--validateName--',
            '--datetime--',
            '--namespace--',
            '--fileDescription--'
        ],
            [$this->className, date("Y-m-d H:i:s"), $currentNameSpace, $this->fileDescription],
            $validatorStub);

        //判断如果存在,则提醒用户是否覆盖
        $createFile = $validatorPath . self::DS . $this->className . 'Validator.php';
        $createFlag = true;

        if (file_exists($createFile) && !$this->option('force')) {
            //提示用户是否替换,如果不 则不生成
            $createFlag = $this->confirm($this->className . 'Validator.php' . ' 文件已存在,是否替换');
        }

        if (!$createFlag) {
            return false;
        }
        $fileSize = file_put_contents($createFile, $content);

        $this->info($createFile . ' 文件创建成功' . $fileSize);
    }


    private function createManager()
    {

        $managerStub = <<<'TOT'
<?php

namespace --managerName--;

use App\Components\Core\DatabaseManager;
use App\Components\Core\DatabaseService;
use --serviceNamespace--\--managerName--Service;

/**
 * --fileDescription--
 * Class --managerName--Manager
 * @date --datetime--
 */
class --managerName--Manager extends DatabaseManager
{

    public function getService(): DatabaseService
    {
        return new --managerName--Service();
    }
}

TOT;
        $managerPath = config('yz_scaffold.manager_path');
        $managerPath = app_path() . str_replace(app_path(), '', $managerPath);

        $currentNameSpace = $this->calculationNameSpace($managerPath);
        $serviceNamespace = $this->calculationNameSpace(config('yz_scaffold.service_path'));

        $content = str_replace([
            '--managerName--',
            '--datetime--',
            '--namespace--',
            '--serviceNamespace--',
            '--fileDescription--'
        ],
            [$this->className, date("Y-m-d H:i:s"), $currentNameSpace, $serviceNamespace, $this->fileDescription],
            $managerStub);

        //判断如果存在,则提醒用户是否覆盖
        $createFile = $managerPath . self::DS . $this->className . 'Manager.php';
        $createFlag = true;

        if (file_exists($createFile) && !$this->option('force')) {
            //提示用户是否替换,如果不 则不生成
            $createFlag = $this->confirm($this->className . 'Manager.php' . ' 文件已存在,是否替换');
        }

        if (!$createFlag) {
            return false;
        }
        $fileSize = file_put_contents($createFile, $content);

        $this->info($createFile . ' 文件创建成功' . $fileSize);
    }

    /**
     * 创建service
     * createService
     * @return bool
     *
     */
    private function createService()
    {
        $serviceStub = <<<'TOT'
<?php

namespace --namespace--;

use App\Components\Core\DatabaseService;
use App\Components\Core\Model;
use --modelNamespace--\--serviceName--Model;

/**
 * --fileDescription--
 * Class --serviceName--Service
 * @date --datetime--
 */
class --serviceName--Service extends DatabaseService {

    /**
     * @inheritDoc
     */
    public function getModel(): Model
    {
        return new --serviceName--Model();
    }
}

TOT;
        $servicePath = config('yz_scaffold.service_path');
        $servicePath = app_path() . str_replace(app_path(), '', $servicePath);

        $modelNamespace = $this->calculationNameSpace(config('yz_scaffold.model_path'));
        $currentNameSpace = $this->calculationNameSpace($servicePath);


        $content = str_replace([
            '--serviceName--',
            '--datetime--',
            '--namespace--',
            '--modelNamespace--',
            '--fileDescription--'
        ],
            [$this->className, date("Y-m-d H:i:s"), $currentNameSpace, $modelNamespace, $this->fileDescription],
            $serviceStub);

        //判断如果存在,则提醒用户是否覆盖
        $createFile = $servicePath . self::DS . $this->className . 'Service.php';
        $createFlag = true;

        if (file_exists($createFile) && !$this->option('force')) {
            //提示用户是否替换,如果不 则不生成
            $createFlag = $this->confirm($this->className . 'Service.php' . ' 文件已存在,是否替换');
        }

        if (!$createFlag) {
            return false;
        }
        $fileSize = file_put_contents($createFile, $content);

        $this->info($createFile . ' 文件创建成功' . $fileSize);
    }

    /**
     * 创建model
     * createModel
     * @return bool
     *
     */
    private function createModel()
    {
        $modelSub = <<<'TOT'
<?php

namespace --namespace--;

use App\Components\Core\Model;

/**
 * --fileDescription--
 * Class --modelName--Model
 * @date --datetime--
 */
class --modelName--Model extends Model{

    protected $table='--tableName--';

    protected $connection='--connectionName--';

}


TOT;
        $modelPath = config('yz_scaffold.model_path');
        $modelPath = app_path() . str_replace(app_path(), '', $modelPath);

        $currentNameSpace = $this->calculationNameSpace($modelPath);

        $content = str_replace([
            '--modelName--',
            '--datetime--',
            '--namespace--',
            '--connectionName--',
            '--fileDescription--',
            '--tableName--'
        ],
            [
                $this->className,
                date("Y-m-d H:i:s"),
                $currentNameSpace,
                $this->connection,
                $this->fileDescription,
                $this->tableName
            ],
            $modelSub);

        //判断如果存在,则提醒用户是否覆盖
        $createFile = $modelPath . self::DS . $this->className . 'Model.php';
        $createFlag = true;

        if (file_exists($createFile) && !$this->option('force')) {
            //提示用户是否替换,如果不 则不生成
            $createFlag = $this->confirm($this->className . 'Model.php' . ' 文件已存在,是否替换');
        }

        if (!$createFlag) {
            return false;
        }
        $fileSize = file_put_contents($createFile, $content);

        $this->info($createFile . ' 文件创建成功' . $fileSize);
    }


    /**
     * 根据路径计算命名空间
     * calculationNameSpace
     *
     * @date 2020/5/7 21:04
     * @param $path
     * @return string
     */
    private function calculationNameSpace($path)
    {
        //计算根目录 app path
        $basePath = app_path();
        $tempPath = str_replace(['/', '\\'], self::DS, str_replace($basePath, '', $path));
        return "App" . self::DS . trim($tempPath, self::DS);
    }

    /**
     * 删除创建的模块
     * delModule
     * @param $module
     *
     * @date 2020/5/7 22:32
     */
    private function delModule($module)
    {

        $path = config('yz_scaffold.controller_path');
        $path = app_path() . str_replace(app_path(), '', $path);
        $file = $path . self::DS . ucfirst($module) . 'Controller.php';
        file_exists($file) && unlink($file) && $this->info($file . ' 删除成功');


        $path = config('yz_scaffold.service_path');
        $path = app_path() . str_replace(app_path(), '', $path);
        $file = $path . self::DS . ucfirst($module) . 'Service.php';
        file_exists($file) && unlink($file) && $this->info($file . ' 删除成功');


        $path = config('yz_scaffold.manager_path');
        $path = app_path() . str_replace(app_path(), '', $path);
        $file = $path . self::DS . ucfirst($module) . 'Manager.php';
        file_exists($file) && unlink($file) && $this->info($file . ' 删除成功');


        $path = config('yz_scaffold.validator_path');
        $path = app_path() . str_replace(app_path(), '', $path);
        $file = $path . self::DS . ucfirst($module) . 'Validator.php';
        file_exists($file) && unlink($file) && $this->info($file . ' 删除成功');


        $path = config('yz_scaffold.model_path');
        $path = app_path() . str_replace(app_path(), '', $path);
        $file = $path . self::DS . ucfirst($module) . 'Model.php';
        file_exists($file) && unlink($file) && $this->info($file . ' 删除成功');


        $this->info($this->option('del_module') . '模块删除成功');
    }

}






下面是laravel框架中一个脚本,写法非常好,可以参考


<?php

namespace Illuminate\Foundation\Console;

use Illuminate\Console\Command;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Support\Arr;
use Illuminate\Support\ServiceProvider;
use League\Flysystem\Adapter\Local as LocalAdapter;
use League\Flysystem\Filesystem as Flysystem;
use League\Flysystem\MountManager;

class VendorPublishCommand extends Command
{
    /**
     * The filesystem instance.
     *
     * @var \Illuminate\Filesystem\Filesystem
     */
    protected $files;

    /**
     * The provider to publish.
     *
     * @var string
     */
    protected $provider = null;

    /**
     * The tags to publish.
     *
     * @var array
     */
    protected $tags = [];

    /**
     * The console command signature.
     *
     * @var string
     */
    protected $signature = 'vendor:publish {--force : Overwrite any existing files}
                    {--all : Publish assets for all service providers without prompt}
                    {--provider= : The service provider that has assets you want to publish}
                    {--tag=* : One or many tags that have assets you want to publish}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Publish any publishable assets from vendor packages';

    /**
     * Create a new command instance.
     *
     * @param  \Illuminate\Filesystem\Filesystem  $files
     * @return void
     */
    public function __construct(Filesystem $files)
    {
        parent::__construct();

        $this->files = $files;
    }

    /**
     * Execute the console command.
     *
     * @return void
     */
    public function handle()
    {
        $this->determineWhatShouldBePublished();

        foreach ($this->tags ?: [null] as $tag) {
            $this->publishTag($tag);
        }

        $this->info('Publishing complete.');
    }

    /**
     * Determine the provider or tag(s) to publish.
     *
     * @return void
     */
    protected function determineWhatShouldBePublished()
    {
        if ($this->option('all')) {
            return;
        }

        [$this->provider, $this->tags] = [
            $this->option('provider'), (array) $this->option('tag'),
        ];

        if (! $this->provider && ! $this->tags) {
            $this->promptForProviderOrTag();
        }
    }

    /**
     * Prompt for which provider or tag to publish.
     *
     * @return void
     */
    protected function promptForProviderOrTag()
    {
        $choice = $this->choice(
            "Which provider or tag's files would you like to publish?",
            $choices = $this->publishableChoices()
        );

        if ($choice == $choices[0] || is_null($choice)) {
            return;
        }

        $this->parseChoice($choice);
    }

    /**
     * The choices available via the prompt.
     *
     * @return array
     */
    protected function publishableChoices()
    {
        return array_merge(
            ['<comment>Publish files from all providers and tags listed below</comment>'],
            preg_filter('/^/', '<comment>Provider: </comment>', Arr::sort(ServiceProvider::publishableProviders())),
            preg_filter('/^/', '<comment>Tag: </comment>', Arr::sort(ServiceProvider::publishableGroups()))
        );
    }

    /**
     * Parse the answer that was given via the prompt.
     *
     * @param  string  $choice
     * @return void
     */
    protected function parseChoice($choice)
    {
        [$type, $value] = explode(': ', strip_tags($choice));

        if ($type === 'Provider') {
            $this->provider = $value;
        } elseif ($type === 'Tag') {
            $this->tags = [$value];
        }
    }

    /**
     * Publishes the assets for a tag.
     *
     * @param  string  $tag
     * @return mixed
     */
    protected function publishTag($tag)
    {
        $published = false;

        foreach ($this->pathsToPublish($tag) as $from => $to) {
            $this->publishItem($from, $to);

            $published = true;
        }

        if ($published === false) {
            $this->error('Unable to locate publishable resources.');
        }
    }

    /**
     * Get all of the paths to publish.
     *
     * @param  string  $tag
     * @return array
     */
    protected function pathsToPublish($tag)
    {
        return ServiceProvider::pathsToPublish(
            $this->provider, $tag
        );
    }

    /**
     * Publish the given item from and to the given location.
     *
     * @param  string  $from
     * @param  string  $to
     * @return void
     */
    protected function publishItem($from, $to)
    {
        if ($this->files->isFile($from)) {
            return $this->publishFile($from, $to);
        } elseif ($this->files->isDirectory($from)) {
            return $this->publishDirectory($from, $to);
        }

        $this->error("Can't locate path: <{$from}>");
    }

    /**
     * Publish the file to the given path.
     *
     * @param  string  $from
     * @param  string  $to
     * @return void
     */
    protected function publishFile($from, $to)
    {
        if (! $this->files->exists($to) || $this->option('force')) {
            $this->createParentDirectory(dirname($to));

            $this->files->copy($from, $to);

            $this->status($from, $to, 'File');
        }
    }

    /**
     * Publish the directory to the given directory.
     *
     * @param  string  $from
     * @param  string  $to
     * @return void
     */
    protected function publishDirectory($from, $to)
    {
        $this->moveManagedFiles(new MountManager([
            'from' => new Flysystem(new LocalAdapter($from)),
            'to' => new Flysystem(new LocalAdapter($to)),
        ]));

        $this->status($from, $to, 'Directory');
    }

    /**
     * Move all the files in the given MountManager.
     *
     * @param  \League\Flysystem\MountManager  $manager
     * @return void
     */
    protected function moveManagedFiles($manager)
    {
        foreach ($manager->listContents('from://', true) as $file) {
            if ($file['type'] === 'file' && (! $manager->has('to://'.$file['path']) || $this->option('force'))) {
                $manager->put('to://'.$file['path'], $manager->read('from://'.$file['path']));
            }
        }
    }

    /**
     * Create the directory to house the published files if needed.
     *
     * @param  string  $directory
     * @return void
     */
    protected function createParentDirectory($directory)
    {
        if (! $this->files->isDirectory($directory)) {
            $this->files->makeDirectory($directory, 0755, true);
        }
    }

    /**
     * Write a status message to the console.
     *
     * @param  string  $from
     * @param  string  $to
     * @param  string  $type
     * @return void
     */
    protected function status($from, $to, $type)
    {
        $from = str_replace(base_path(), '', realpath($from));

        $to = str_replace(base_path(), '', realpath($to));

        $this->line('<info>Copied '.$type.'</info> <comment>['.$from.']</comment> <info>To</info> <comment>['.$to.']</comment>');
    }
}