在 Laravel 迁移中使用动态数据库连接



我的应用程序有多个客户端,每个客户端都有自己的数据库。客户端的应用程序是基于插件的,因此每个客户端的表具有相同的结构。但是客户端 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 (AppModelsClientsClient::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 界面添加,因此当前连接必须可动态设置。

您的连接已被 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');
}

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

最新更新