动态 env-files(多个数据库)和 artisan 命令

Dynamic env-files (multiple databases) and artisan commands

我有一个大型项目,每个客户都在自己单独的数据库中。为了让它工作,我们使用自定义 .env-loader 加载每个客户 .env 通过检查客户子域(每个客户唯一)。

然而,这当然不适用于 artisan 命令。例如,当我要迁移时,我将需要一次迁移所有数据库。所以我设置了一个 Artisan 命令来获取 .env 文件并循环遍历它们,然后调用默认的 artisan migrate。但它没有按预期工作。

我什么都试过了;例如:

$dotenv = new Dotenv('/env', '.test.env');
$dotenv->overload();

并且:

app()->useEnvironmentPath('/env');
app()->loadEnvironmentFrom('.test.env');

甚至:

config('database.connections.mysql.database', 'test_database');

一旦我 运行 $this->call('migrate'); 应用默认为默认 .env 并在 运行 时忽略所有自定义。有谁知道我如何重载数据库的迁移命令选择?

注意: 我知道我可以在 config/database.php 中手动设置多个连接(例如:Overriding Default Laravel database configuration for artisan migrate commands),但是,图像有几十个客户,这不可行。

我不得不对控制台命令创建的 SQLite 数据库做一些类似的事情,我可以迁移到 运行 的唯一方法是动态创建数据库配置:

Config::set('database.connections.'.$config_key, array(
            'driver'   => 'sqlite',
            'database' => storage_path($database_name),
            'prefix'   => '',
));

然后我会调用迁移命令:

  Artisan::call('migrate', [
        '--database' => $config_key,
        '--path' => 'database/offline/'.$type.'/migrations',
    ]);

经过一大堆问题后,我可以这样排序;

在 Laravel 5 中,Config::set()config('config',['key' => 'value])config()-set('config', ['key' => 'value']) 似乎有所不同。

经过大量测试不同的变体后,我们设法通过这种方式获得了解决方案;

$connection = 'connection';
$iterator = 0;

foreach ($files as $file) {
    App::useEnvironmentPath('/env');
    App::loadEnvironmentFrom('.file.env');

    // Create a new connection "on the fly"
    config()->set('database.connections.' . $connection . '_' . $iterator, [
        'driver'    => 'mysql',
        'host'      => env('DB_HOST'),
        'database'  => env('DB_DATABASE'),
        'username'  => env('DB_USERNAME'),
        'password'  => env('DB_PASSWORD'),
        'charset'   => 'utf8',
        'collation' => 'utf8_unicode_ci',
        'prefix'    => '',
        'strict'    => false,
    ]);

    // Call regular migration command
    $this->call('migrate', ['--force' => true, '--database' => $connection . '_' . $iterator]);

    $iterator++;
}

这设法为 MySQL-database 设置多个新连接,然后为每个连接设置种子。

感谢 @David Allen 的启发。