Laravel:动态连接数据库

34

我正在使用Laravel 5(.1)创建一个应用程序,需要连接不同的数据库。唯一的问题是不知道要连接哪些数据库,因此无法使用config中的database.php文件。控制器负责使用动态给定的连接细节进行连接。

我该如何创建一个新的数据库连接,包括使用DB类?(或者这种操作是否可行)

提前感谢您的回复!


@PhiterFernandes 系统管理员可以填写凭据,这些凭据将被加密并存储在数据库中以备后用。 - Roboroads
8个回答

55

最简单的解决方案是在运行时设置数据库配置。Laravel 可能期望从 config/database.php 文件中加载这些设置,但这并不意味着您不能稍后设置或更改它们。

config/database.php 加载的配置存储为 Laravel 配置中的 database。也就是说,config/database.php 内部的 connections 数组存储在 database.connections 中。

因此,您可以像这样轻松地覆盖/更改这些连接:

Config::set("database.connections.mysql", [
    "host" => "...",
    "database" => "...",
    "username" => "...",
    "password" => "..."
]);

从那时起,使用这个 mysql 连接的任何 Eloquent 模型都将使用这个新的数据库连接配置。

如果可能的话,我建议在服务提供者中执行此操作。


使用这个,是否也可以添加连接而不仅仅是更改已加载的连接? - Roboroads
我将尝试在运行时设置数据库。我无法确定每个页面加载需要打开多少连接,因此预定义有点不可能。再次感谢您的答复! - Roboroads
1
@Roboroads 你会同时使用多个连接吗?我自己连接了200多个数据库,但每次只连接一个。所以我只需更改相同的连接配置数组。 - jszobody
3
抱歉重新打开过去的讨论,这个问题与迁移有什么关系? - Daniel Casserly
1
@DanielCasserly 应该可以正常工作,只要您在服务提供程序中设置数据库配置,以便在 Laravel 运行迁移时准备就绪。我正在使用此方法进行具有自定义数据库设置的迁移,没有问题。 - jszobody
显示剩余7条评论

31

我遇到了同样的问题。

实际上,您可以在运行时更改数据库设置并使用它们。

使用config()函数来设置额外的连接设置或覆盖现有的连接设置。

config(['database.connections.mynewconnection' => {settings here}]);

请记住,这些设置是被缓存的。因此,当您需要使用新的设置时,请清除要使用的连接的数据库缓存。

DB::purge('mynewconnection');

您还可以操作使用的默认连接。如果您希望在不同的连接上使用迁移并通过迁移表在使用的连接中跟踪它们,这将非常方便。当然,还有其他很酷的用途...

DB::setDefaultConnection('mynewconnection');

2
我错过了DB :: purge(...);。 - AMIB

13

可能需要使用这些:

use Illuminate\Support\Facades\Config;
use DB;

设置数据库配置:

        Config::set("database.connections.mysql_external", [
            'driver' => 'mysql',
            "host" => "localhost",
            "database" => "db_name",
            "username" => "root",
            "password" => "root",
            "port" => '8889',
            'charset'   => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix'    => '',
            'strict'    => false,
        ]);

连接到数据库并执行操作:

    $users = DB::connection('mysql_external')->select('Select id from users');

断开数据库连接并重置配置变量

        DB::disconnect('mysql_external');
        Config::set("database.connections.mysql_external", [
            'driver' => 'mysql',
            "host" => "localhost",
            "database" => "",
            "username" => "",
            "password" => "",
            "port" => '',
            'charset'   => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix'    => '',
            'strict'    => false,
        ]);

断开连接对我很有帮助。Laravel会自动使用新配置重新连接。 - StR

5

我也遇到了这个问题,是在使用一个脚本将多个MS Access DB文件导入MySQL时。我不满意任何建议在运行时编辑配置的解决方案。为每个要导入的Access DB文件动态创建一个新配置非常丑陋和混乱。经过一些尝试,我成功地让Laravel通过以下方式切换现有连接的DB:

$mysqlConn = DB::connection();
$mysqlConn->getPdo()->exec("USE $schemaName;");
$mysqlConn->setDatabaseName($schemaName);

我试图动态地更改PostgreSQL模式,你的解决方案对我帮助很大!非常感谢你! - undefined

1

//appServiceProvider.php

 Connection::macro('useDatabase', function (string $databaseName) {
            $this->getPdo()->exec("USE `$databaseName`;");
            $this->setDatabaseName($databaseName);
    });

//用法。

  \DB::connection()->useDatabase($dbName);

0
在你的databse.php中创建一个新的数据库连接。
    'connections' => [
        'new_db_connection' => [
            'driver' => 'sqlsrv',
            'host' => env('DB_HOST', 'localhost'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE_NEW', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'charset' => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix' => '',
            'strict' => false,
            'engine' => null,
         ],
       'old_db_connection' => [
            'driver' => 'sqlsrv',
            'host' => env('DB_HOST', 'localhost'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE_OLD', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'charset' => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix' => '',
            'strict' => false,
            'engine' => null,
        ],
     ]

创建辅助方法
static function getDatabaseName()
{
    // Apply your condition and return databse 
    if(url('/') === 'http://localhost:8001'){
        return 'new_db_connection';
    } else {
        return 'old_db_connection';
    }

}

使用查询构建器

   $databaseName = Helper::getDatabaseName();
    DB::connection($databaseName)
    ->table('your table name')
    ->select('*')
    ->get();

使用模型

<?php

namespace App\Models;

use App\Helper;
use Illuminate\Database\Eloquent\Model;

class Test extends Model {

    public function __construct()
    {
       // You can apply the below variable dynamically and model 
       // will use that new connection
        $this->connection = Helper::getDatabaseName();

    }

    protected $table = "users";
}

0
// Without Using any Facades
    
    config(['database.connections.mynewconnection' => [
        'driver' => 'sqlsrv',
        'host' => env('DB_HOST', 'localhost'),
        'port' => env('DB_PORT', '3306'),
        'database' => env('DB_DATABASE_OLD', 'forge'),
        'username' => env('DB_USERNAME', 'forge'),
        'password' => env('DB_PASSWORD', ''),
        'charset' => 'utf8',
        'collation' => 'utf8_unicode_ci',
        'prefix' => '',
        'strict' => false,
        'engine' => null,  
    ]]);


// With Facades
// Use Illuminate\Support\Facades\Config;

Config::set('database.connections.mynewconnection', [
    'driver' => 'sqlsrv',
    'host' => env('DB_HOST', 'localhost'),
    'port' => env('DB_PORT', '3306'),
    'database' => env('DB_DATABASE_OLD', 'forge'),
    'username' => env('DB_USERNAME', 'forge'),
    'password' => env('DB_PASSWORD', ''),
    'charset' => 'utf8',
    'collation' => 'utf8_unicode_ci',
    'prefix' => '',
    'strict' => false,
    'engine' => null,              
]);

使用查询构建器访问数据库

DB::connection('mynewconnection')->table()->get();


-1

这不是有效的PHP语法。 - Roboroads

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接