Laravel implements custom generation file commands


Foreword

The Entiy file is used in the current project, and the corresponding Entiy file must be created every time a table is added. , It is very troublesome to set variables at the same time. So I wonder if I can create a command like make:controller to generate Entity files.

The file creation commands like php artisan make:model in laravel are inherited from Illuminate\Console\GeneratorCommand. The principle of implementing such a command is actually very simple:

First write a template file, then define keywords, and finally replace the keywords with what we want in command Content.

template file (stub)

Look at make:command: his The template is model.stub, located at vendor\laravel\framework\src\Illuminate\Foundation\Console\stubs\model.stub.


namespace DummyNamespace;

use Illuminate\Database\Eloquent\Model;

class DummyClass extends Model
{
//
}

From the perspective of model.stub, when we use php artisan make:model to create a model, we only replace the namespace keyword DummyNamespace and the class name keyword DummyClass.

GeneratorCommand

make:model command The corresponding class is ModelMakeCommand, located in the parent directory of model.stub. The content is too much, so I won’t post it, and you can check it out if you are interested. Look directly at its parent class Illuminate\Console\GeneratorCommand.

// core code public function handle(){ // splicing namespace $name = $ this->qualifyClass($this->getNameInput()); // Get the file storage location $path = $this->getPath($name); // Determine whether the file exists, and throw an error if ((! $ this->hasOption('force') ||! $this->option('force')) && $this->alreadyExists($this->getNameInput())) {$this->error($this-> type.' already exists!'); return false;} // Generate files $this->makeDirectory($path); // Replace keywords in the template, such as: command space and class name $this->files-> put($path, $this->buildClass($name)); $this->info($this->type.' created successfully.');}// Edit template content protected function buildClass($name){ / / Get template file content $stub = $this->files->get($this->getStub()); return $this->replaceNamespace($stub, $name)->replaceClass($stub, $name); }// Replace the namespace DummyRootNamespace protected function replaceNamespace(&$stub, $name){ // Splice the namespace $stub = str_replace( ['DummyNamespace','DummyRootNamespace','Namesp acedDummyUserModel'], [$this->getNamespace($name), $this->rootNamespace(), config('auth.providers.users.model')], $stub ); return $this;)// Replacement class Name DummyClassprotected function replaceClass($stub, $name){ $class = str_replace($this->getNamespace($name).'\\','', $name); return str_replace('DummyClass', $class, $ stub);}

As you can see from the source code, creating a file is just to replace the keywords in the template. On this basis, we can implement some commands to generate the files we want.


implementation create:entity command

1. Create template

namespace DummyNamespace;

class DummyClass extends Entity
{
// custom content keywords that need to be replaced
AAA
}

2. implement command

class CreateEntity extends GeneratorCommand{ protected $signature ='create:entity {name}'; protected $description ='Automatically generate Model Entity instance'; // Database type comparison public static $dictionary = ['string' => ['char','text'],'int' => ['int','numeric '],'float' => ['double','float','decimal'] ]; protected $type ='entity'; /** * Set template address* @return string */ protected function getStub() { return __DIR__.'/stubs/Entity.stub';} /** * Set the namespace and file path* @param string $rootNamespace * @return string */ protected function getDefaultNamespace($rootNamespace) {return $rootNamespace.'\ Repositories\Entitys'; //Be lazy, write directly to death} /** * Set the class name and custom replacement content* @param string $stub * @param string $name * @return string */ protected function replaceClass($stub, $name) {$stub = $this->replaceCustomizeSetting($ stub); //Replace custom content return parent::replaceClass($stub, $name);} /** * Replace custom content* @param $stub * @return mixed */ protected function replaceCustomizeSetting($stub){ //Process the input class name into table name $name = $this->getNameInput(); $name = rtrim($name,'E'); $tableName = strtolower(trim(preg_replace("/[AZ]/ ", "_\\0",$name), "_")); //The hump becomes lowercase plus _ $info = collect(\DB::select("desc rxt_".$tableName.";") )->toArray(); //Get a list of table fields and types$list = []; foreach ($info as $key => $value){ //Convert to a two-dimensional array $arr = collect($info[$ key])->toArray(); if($arr['Field'] =='deleted_at') continue; array_push($list, $arr);} $fieldExample = "/** \r\n * @var type isNull \r\n */ \r\n public \$fieldName;\r\n"; $result = null; foreach ($list as $item){ $result = $result.$fieldExample; foreach (static::$dictionary as $key => $value){ foreach ($value as $a => $b ){ if(strstr($item['Type'], $b)){ $result = str_replace('type', $key, $result);}}} $isNull = $item['Null'] == 'YES'?'|null':''; $result = str_replace('isNull', $isNull, $result); $result = str_replace('fieldName', $item['Field'], $result);} return str_replace('AAA', $result, $stub);} }

Leave a Comment

Your email address will not be published.