我尝试创建自定义laravel(5.2)迁移命令,该命令与migrate:status
基本相同,只是它只列出了待处理的迁移而不是所有迁移。
要做到这一点,我只需将migrate:status
复制到我的app / console目录中的另一个类中,并调整代码以满足我的需要。但是每当我尝试运行它时都会出错:
[照亮\合同\容器\ BindingResolutionException] 构建[App \ Console \ Commands \ PendingMigrations,Illuminate \ Database \ Migrations \ Migrator]时,目标[Illuminate \ Database \ Migrations \ MigrationRepositoryInterface]无法实例化。
类本身的内容和fire()
方法似乎并不重要,因为它没有达到那么远,它在__construct()
方法中失败。
<?php namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Database\Migrations\Migrator;
class PendingMigrations extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'migrate:pending';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Shows a list of pending migrations';
/**
* The migrator instance.
*
* @var \Illuminate\Database\Migrations\Migrator
*/
protected $migrator;
/**
* Create a new migration rollback command instance.
*
* @param \Illuminate\Database\Migrations\Migrator $migrator
* @return \Illuminate\Database\Console\Migrations\StatusCommand
*/
public function __construct(Migrator $migrator)
{
parent::__construct();
$this->migrator = $migrator;
}
/**
* Execute the console command.
*
* @return void
*/
public function fire()
{
}
}
它的原因可能与IoC容器和加载内容的顺序有关,但我对Laravel的内部工作原理知之甚少。
肯定有可能吗?
我目前停留在5.2,所以我不确定这个问题是否存在于更新的版本中。
我到目前为止唯一尝试的是将迁移服务提供商添加到config/app.php
列表的顶部,但它似乎没有影响,而且它只是一个随机的无论如何猜。
providers' => [
Illuminate\Database\MigrationServiceProvider::class,`
]
答案 0 :(得分:9)
我用这个来解决这个问题:
$this->migrator = app('migrator');
但它不一定是最好的方法
答案 1 :(得分:2)
Migrator
实例未绑定到IoC容器中的类名,而是绑定到migrator
别名。
来自Illuminate\Database\MigrationServiceProvider
:
/**
* Register the migrator service.
*
* @return void
*/
protected function registerMigrator()
{
// The migrator is responsible for actually running and rollback the migration
// files in the application. We'll pass in our database connection resolver
// so the migrator can resolve any of these connections when it needs to.
$this->app->singleton('migrator', function ($app) {
$repository = $app['migration.repository'];
return new Migrator($repository, $app['db'], $app['files']);
});
}
由于类名称未绑定在IoC容器中,因此当Laravel解析您的命令并尝试解析Migrator
依赖项时,它将尝试从头开始构建一个新的依赖项,但由于Illuminate\Database\Migrations\MigrationRepositoryInterface
而失败也不绑定在IoC容器中(因此会收到您收到的错误)。
由于Laravel无法自行解决,因此您需要为Migrator
类名注册绑定,或者需要为命令注册绑定。 Laravel本身在Illuminate\Foundation\Providers\ArtisanServiceProvider
中注册了命令的所有绑定。 command.migrate
绑定的示例:
/**
* Register the command.
*
* @return void
*/
protected function registerMigrateCommand()
{
$this->app->singleton('command.migrate', function ($app) {
return new MigrateCommand($app['migrator']);
});
}
因此,在您的AppServiceProvider
或您设置的其他服务提供商中,您可以添加以下内容之一:
在IoC中注册命令:
$this->app->singleton(\App\Console\Commands\PendingMigrations::class, function ($app) {
return new \App\Console\Commands\PendingMigrations($app['migrator']);
});
或者,在IoC中注册Migrator类名称:
$this->app->singleton(\Illuminate\Database\Migrations\Migrator::class, function ($app) {
return $app['migrator'];
});
答案 2 :(得分:0)
由于我不想在应用程序中的任何地方注册migrator
,但是我仍然想扩展MigrateCommand
本身,因此我想出了一种方法来按原样维护我的应用程序:
public function __construct()
{
app()->singleton(\App\Console\Commands\PendingMigrations::class, function ($app) {
return new \App\Console\Commands\PendingMigrations($app['migrator']);
});
parent::__construct(app('migrator'));
}