Php 可以修改artisan migrate命令创建的模板吗?

Php 可以修改artisan migrate命令创建的模板吗?,php,laravel,laravel-4,migration,Php,Laravel,Laravel 4,Migration,我已经为我的迁移创建了一个基类。目前,我运行artisan migrate命令,它创建了一个扩展迁移文件的新迁移,但是我希望包括我的BaseMigration并从那里扩展它。我一直在手动地做这些改变,但我觉得我在不必要地重复我自己 关于如何让新迁移自动扩展和加载我的基本迁移,有什么建议吗?我认为您不能,因为Laravel从供应商/Laravel/framework/src/Lightning/Database/migrations/stubs文件夹进行迁移,您无法更改,但您有一些选择: 1) 创

我已经为我的迁移创建了一个基类。目前,我运行artisan migrate命令,它创建了一个扩展迁移文件的新迁移,但是我希望包括我的BaseMigration并从那里扩展它。我一直在手动地做这些改变,但我觉得我在不必要地重复我自己


关于如何让新迁移自动扩展和加载我的基本迁移,有什么建议吗?

我认为您不能,因为Laravel从
供应商/Laravel/framework/src/Lightning/Database/migrations/stubs
文件夹进行迁移,您无法更改,但您有一些选择:

1) 创建自己的artisan命令
migrate:makemyown

2) 使用。它们允许您通过执行以下操作来创建迁移:

php artisan generate:migration create_posts_table --fields="title:string, description:text"
如果您只需要从一些字段开始,而没有比这些字段更具体的字段,那么它的效果非常好


3) 编辑Laravel存根,但问题是,一旦
composer更新
,它们可能会被composer覆盖。

对于Laravel 5,您需要在以下位置编辑一个
。存根
文件:

vendor/laravel/framework/src/Illuminate/Database/Migrations/stubs
没有理由不能编辑这些文件


vendor/laravel/framework/src/
中搜索
.stub
文件,以查找artisan使用的所有其他stub(模板)。

我认为(目前)没有办法覆盖它,但我认为您可以创建使用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'],
      ];
  }

}
<?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.';
  }

}
<?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',
    ...
  ];
最后,您可以创建第一个生成器类
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';
  }

}
将存根放在
resources/stubs
目录下。让我们为请求生成器
资源/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;
  }

}

至少在Laravel 5中,它是以相当合理的方式实现的

子类
MigrationCreator
并重写
getStubPath()
,只需将函数从原始类复制过来(它将使用子类的
\uuuu DIR\uuu

将您的服务提供商添加到默认服务提供商之后的
config/app.php

最后,在MigrationCreator子类旁边复制
vendor/laravel/framework/src/illighte/Database/Migrations/stubs
(在本例中,它将成为
app/Database/stubs
),并根据需要编辑模板

保留
DummyClass
DummyTable
名称,将它们替换为
str_replace()
,以创建实际的迁移文件。

自Laravel 7以来,您可以使用
php artisan存根:publish

已发布的存根将位于应用程序根目录中的
stubs
目录中。使用Artisan
make
命令生成相应的类时,将反映对这些存根所做的任何更改


这是一种糟糕的做法,您应该真正避免编辑您不拥有的库。例如,如果有一个新版本的Laravel,并且您希望对其进行更新,那么您无法在不丢失所做更改的情况下进行更新。您应该覆盖该文件,而不是从供应商处更新原始文件,因为它将被Laravel的更新覆盖。您不希望每次更新Laravel时都更新.stub。我强烈推荐Jeffrey Way的Laravel生成器。上面的链接已断开,您可能应该使用他的版本5生成器,可以找到。@Antonio”文件夹,您无法更改该文件夹“您在选项3中解释了如何更改它,因此前面的这句话增加了不必要的歧义。我可能会在你的介绍段落中加入数字3,并警告你在运行
composer update
时会丢失更改。这对读者来说会更清楚。谢谢你的回答!如果有人感兴趣,我制作了一个解决这个问题的软件包L5+值得注意的是,Laravel 7以一种更直接的方式解决了这个问题。见下面的答案,这是一个相当合乎逻辑的方式可行。不知道我是否会称之为“相当简单:)注意类名
AppMigrationServiceProvider
非常重要,因为Laravel似乎无法处理我自己的
MigrationServiceProvider
。是的,甚至它的名称空间也肯定与内置名称空间不同。@Tobia
getStubPath()
已更改为
stubPath()
。您可能需要执行
php artisan config:cache
,然后才能更新
应用程序提供程序
缓存。
<?php

namespace App\Database;

use Illuminate\Database\Migrations\MigrationCreator;

class AppMigrationCreator extends MigrationCreator
{
    public function getStubPath()
    {
        return __DIR__.'/stubs';
    }
}
<?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'];
    }
}