有没有关于如何让新的迁移自动扩展和加载我的基本迁移的建议?
在 Laravel 5 中可以以相当合理的方式实现。
继承 MigrationCreator
并重写 getStubPath()
,只需从原始类中复制该函数(它将使用您子类的__DIR__
)。
<?php
namespace App\Database;
use Illuminate\Database\Migrations\MigrationCreator;
class AppMigrationCreator extends MigrationCreator
{
public function getStubPath()
{
return __DIR__.'/stubs';
}
}
编写一个服务提供者以使用你自己的子类覆盖 migration.creator
(它必须是一个延迟服务提供者,因为你不能用急切的绑定来覆盖延迟的绑定):
<?php
namespace App\Database;
use Illuminate\Support\ServiceProvider;
class AppMigrationServiceProvider extends ServiceProvider
{
protected $defer = true;
public function register()
{
$this->app->singleton('migration.creator', function ($app) {
return new AppMigrationCreator($app['files']);
});
}
public function provides()
{
return ['migration.creator'];
}
}
将您的服务提供者添加到config/app.php
中默认提供者之后。
最后,将vendor/laravel/framework/src/Illuminate/Database/Migrations/stubs
复制到您的MigrationCreator子类旁边(在本示例中,它将变为app/Database/stubs
),并根据需要编辑模板。
保留DummyClass
和DummyTable
名称,因为它们将使用str_replace()
替换为实际的迁移文件。
AppMigrationServiceProvider
非常重要,因为Laravel似乎无法处理我的自定义MigrationServiceProvider
。是的,即使它的命名空间肯定不同于内置的命名空间... - mpywgetStubPath()
已更改为stubPath()
。 - zrkbphp artisan config:cache
命令以更新您的app.providers
缓存。 - Boris D. Teoharov自Laravel 7起,您可以使用php artisan stub:publish
命令发布存根文件。
发布的存根文件将位于应用程序根目录下的
stubs
目录中。当您使用Artisan的make
命令生成相应的类时,对这些存根文件所做的任何更改都将反映出来。
我不认为你可以这样做,因为Laravel从vendor/laravel/framework/src/Illuminate/Database/Migrations/stubs
文件夹中获取迁移,并且你不能更改它,但你有一些选择:
1) 创建自己的artisan命令migrate:makemyown
。
2) 使用 Jeffrey Way's Laravel Generators。他们让你通过以下方式创建迁移:
php artisan generate:migration create_posts_table --fields="title:string, description:text"
我认为现在还没有办法覆盖这个(现在),但我认为你可以创建自定义命令,使用Laravel的逻辑。这是为Laravel 5创建的。
首先,您需要创建生成器命令 app/Console/Commands/Generator.php
:
<?php namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Filesystem\Filesystem;
use Symfony\Component\Console\Input\InputArgument;
class Generator extends Command
{
/**
* Command name
*
* @var string
*/
protected $name = 'generate';
/**
* Command description
*
* @var string
*/
protected $description = 'Custom object generator';
/**
* An array with all available generator classes
*
* @var array
*/
protected $types = ['request', 'model', 'middleware'];
/**
* Execute command
*
* @return mixed
*/
public function handle()
{
$type = $this->argument('type');
if (!in_array($type, $this->types)) {
return $this->error('Type must be one of: '.implode(', ', $this->types));
}
// Create new instance
$generatorClass = 'App\Console\Commands\Generators\\'.ucfirst($type);
$generator = new $generatorClass(new Filesystem());
// Each generator has "fire" method
$this->comment($generator->setClassName($this->argument('name'))->fire());
}
/**
* @return array
*/
public function getArguments()
{
return [
['type', InputArgument::REQUIRED, 'Type of class to generate: '.implode(', ', $this->types)],
['name', InputArgument::REQUIRED, 'Name of class to generate'],
];
}
}
然后,您需要为所有Generators类创建一个抽象类app/Console/Commands/Generators/Generator.php
:
<?php namespace App\Console\Commands\Generators;
use Illuminate\Console\GeneratorCommand;
abstract class Generator extends GeneratorCommand
{
// Directory name with whole application (by default app)
const APP_PATH = 'app';
/*
* Name and description of command wont be used
* Generators Commands are not loaded via Kernel
* Name and description property has been put just to avoid Exception thrown by Symfony Command class
*/
protected $name = 'fake';
protected $description = 'fake';
/**
* Class name to generate
*
* @var string
*/
protected $className;
/**
* Returns class name to generate
*
* @return string
*/
protected function getNameInput()
{
return $this->className;
}
/**
* Returns path under which class should be generated
*
* @param string $name
* @return string
*/
protected function getPath($name)
{
$name = str_replace($this->getAppNamespace(), '', $name);
return self::APP_PATH.'/'.str_replace('\\', '/', $name).'.php';
}
/**
* Sets class name to generate
*
* @param string $name
* @return $this
*/
public function setClassName($name)
{
$this->className = $name;
return $this;
}
/**
* Execute command
*
* @return string
*/
public function fire()
{
$name = $this->parseName($this->getNameInput());
if ($this->files->exists($path = $this->getPath($name)))
{
return $this->type.' already exists!';
}
$this->makeDirectory($path);
$this->files->put($path, $this->buildClass($name));
return $this->type.' '.$this->className.' created successfully.';
}
}
最后,您可以创建第一个生成器类!app/Console/Commands/Generators/Request.php
<?php namespace App\Console\Commands\Generators;
class Request extends Generator
{
/**
* Class type to generate
*
* @var string
*/
protected $type = 'Request';
/**
* Returns default namespace for objects being generated
*
* @param string $rootNamespace
* @return string
*/
protected function getDefaultNamespace($rootNamespace)
{
return $rootNamespace.'\Http\Requests';
}
/**
* Returns path to custom stub
*
* @return string
*/
public function getStub()
{
return base_path('resources').'/stubs/request.stub';
}
}
app/Console/Kernel.php
中:<?php namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel {
/**
* The Artisan commands provided by your application.
*
* @var array
*/
protected $commands = [
...
'App\Console\Commands\Generator',
...
];
resources/stubs
目录下。让我们为请求生成器创建第一个存根 resources/stubs/request.stub
:<?php namespace {{namespace}};
class {{class}} extends Request
{
/**
* @return bool
*/
public function authorize()
{
// CUSTOM LOGIC
return false;
}
/**
* @return array
*/
public function rules()
{
$rules = [];
// CUSTOM LOGIC
return $rules;
}
}
然后使用 php artisan generate request MyRequest
命令调用。
你可以创建自定义的模型(Model)、中间件(Middleware)、控制器(Controller)等生成器,非常简单 - 你只需要在 app/Commands/Console/Generators
下创建新的生成器类 - 参考 Request.php
生成器,了解它的工作原理!
对于 Laravel 5,您需要编辑以下其中一个 .stub
文件:
vendor/laravel/framework/src/Illuminate/Database/Migrations/stubs
你完全可以编辑这些文件,没有任何理由不能这样做。
在vendor/laravel/framework/src/
中搜索.stub
文件,以找到Artisan使用的所有其他桩(模板)。