【问题标题】:Using a dynamic database connection in a Laravel migration在 Laravel 迁移中使用动态数据库连接
【发布时间】:2020-05-07 04:47:35
【问题描述】:

我的应用程序有多个客户端,每个客户端都有自己的数据库。客户端的应用程序是基于插件的,因此每个客户端的表具有相同的结构。但客户端 A 不一定与客户端 B 拥有相同的表(因为客户端 B 使用更多/其他插件)。

我在database.php 配置文件中创建了一个“客户端”连接:

    'client' => [
        'driver' => 'mysql',
        'url' => env('DATABASE_URL'),
        'host' => env('DB_CLIENT_HOST', '127.0.0.1'),
        'port' => env('DB_CLIENT_PORT', '3306'),
        'database' => env('DB_CLIENT_DATABASE', 'forge'),
        'username' => env('DB_CLIENT_USERNAME', 'forge'),
        'password' => env('DB_CLIENT_PASSWORD', ''),
        // and so on
    ],

在我的迁移文件中,我遍历所有客户端,希望每个客户端重新运行一次迁移:

public function up()
{
    foreach (\App\Models\Clients\Client::all() as $client){

        if($client->hasCompleteDatabaseConnectionDetails()){

            $client->establishDatabaseConnection();

            Schema::connection('client')->create('pages', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->string('meta_title')->nullable();
                $table->string('meta_description')->nullable();
                $table->string('title')->nullable();
                $table->timestamps();
            });
        }
    }
}

最后是我的客户端模型中的相关方法:

public function hasCompleteDatabaseConnectionDetails(): bool
{
    return !is_null($this->db_host)
        && !is_null($this->db_port)
        && !is_null($this->db_user)
        && !is_null($this->db_name)
        && !is_null($this->db_password);
}

public function couldConnectToDatabase(): bool
{
    try {
        DB::connection('client')->statement('SELECT TRUE');
        config(['client.can_connect_to_database' => true]);
    } catch (\Exception $ex) {
        config(['client.can_connect_to_database' => false]);
    }
    return config('client.can_connect_to_database');
}

protected function setDatabaseConnectionInConfig(): void
{
    config(['database.connections.client.host' => $this->db_host]);
    config(['database.connections.client.port' => $this->db_port]);
    config(['database.connections.client.database' => $this->db_name]);
    config(['database.connections.client.username' => $this->db_user]);
    config(['database.connections.client.password' => $this->db_password]);
}

public function establishDatabaseConnection(): void
{
    if ($this->hasCompleteDatabaseConnectionDetails()) {
        config(['client.has_qualified_database_credentials' => true]);
        $this->setDatabaseConnectionInConfig();
        if($this->couldConnectToDatabase()){
            config(['client.can_connect_to_database' => true]);
        } else {
            config(['client.can_connect_to_database' => false]);
        }
    } else {
        config(['client.has_qualified_database_credentials' => false]);
    }
}

当我运行 php artisan migrate 时,我收到一条错误消息,提示无法使用用户 ""@"localhost" 进行连接。所以不知何故,应用程序不保存凭据。我怎样才能解决这个问题? 我不想在database.php 中为每个新客户端添加新连接,因为新客户端应该可以从 Web 界面添加,因此当前连接必须是可动态设置的。

【问题讨论】:

    标签: php laravel migration


    【解决方案1】:

    你的连接已经被 Laravel 缓存了,所以在你运行 DB::purge($connection) 之前,对数据库配置的任何更改都不会产生任何影响。

    public function couldConnectToDatabase(): bool
    {
        try {
            DB::purge('client');
            DB::connection('client')->statement('SELECT TRUE');
            config(['client.can_connect_to_database' => true]);
        } catch (\Exception $ex) {
            config(['client.can_connect_to_database' => false]);
        }
        return config('client.can_connect_to_database');
    }
    

    您可以查看Illuminate\Database\DatabaseManager.php 以获取有关连接如何工作的更多线索/信息。

    【讨论】:

      猜你喜欢
      • 2017-02-23
      • 2019-09-03
      • 2016-07-05
      • 1970-01-01
      • 2016-11-11
      • 2017-08-15
      • 1970-01-01
      • 1970-01-01
      • 2021-04-30
      相关资源
      最近更新 更多