如何在Laravel中使用多个数据库以及如何通过用户更改数据库连接?

时间:2019-08-08 12:15:30

标签: php mysql database laravel-5

我想创建用户数据库,例如在我的系统中有两个用户A和B。我有一个主数据库,以及两个数据库user_a(对于用户A)和user_b(对于用户B)。在主数据库中,我具有所有用户信息。现在我想要的是,当用户A登录系统时,它访问master数据库和user_a数据库,而当用户B登录数据库连接时,应该是master数据库和user_b数据库。

1 个答案:

答案 0 :(得分:1)

这是@ADyson的建议之后我的回答

我在INTERNET上进行了很多搜索,但是没有找到完美的解决方案。 有一些博客只在其中解释了创建两个或多个连接database.php配置文件,然后使用$ connection在模型中访问这些连接。 是的,我同意这是一个很好的解决方案,但是,如果我的系统中有数百万的用户,我不想手动在database.php文件上创建所有连接。

所以我做了一个实验,它为我工作,我想与所有其他开发人员共享该解决方案。

首先,我在主数据库中为所有用户提供一个数据库名称选项(超级管理员可以在系统中添加超级管理员创建的用户的数据库名称)

第二,我创建了一个Middleware DatabaseSwitcher.php,并在Kernel.php中全局注册了该中间件,并在web.php中对auth Middleware进行了身份验证后调用了该中间件:

(['middleware' => ['auth', 'DatabaseSwitcher']]).

下面是中间件的代码。

<?php 
namespace App\Http\Middleware;
use Closure;
use Illuminate\Contracts\Auth\Guard;
use Config;    //to get configuration data
class DatabaseSwitcher {
    /**
     * The Guard implementation.
     *
     * @var Guard
     */
    protected $auth;

    /**
     * Create a new filter instance.
     *
     * @param  Guard  $auth
     * @return void
     */
    public function __construct(Guard $auth)
    {
        $this->auth = $auth;
    }
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {   
        //check if user logged in
        if ( !$this->auth->guest() )
        {    
            //get authenticate user information
            $user = $this->auth->user();
            //get user's database            
            $user_db = $user->user_database;
            //first get default mysql connection array and use in new variable for new connection which will create dynamically.(default connection is defined in database.php config file)
            $dbConfig = config('database.connections.mysql');
            //now use database name which is in user record; 
            $dbConfig['database'] = $user_db;
            //now set a new database connection name is mysql_new in my case 
            Config::set("database.connections.mysql_new", $dbConfig); 
            //now set default connection which is created for the user
            Config::set("database.default", 'mysql_new'); 
            //now there are two connection one for master (mysql) and other for user(mysql_new) and default connection is (mysql_new)
            //we can access these two connection in every models by using $connection as mentioned in Larave documentation.            
        } 
        return $next($request);
    }
}

现在,我们可以通过使用标准结构或类似的laravel在模型中动态使用两个数据库连接:

protected $connection = 'mysql'; 
protected $connection = 'mysql_new'; 

万事俱备,但是当我们使用unique并且存在时,Laravel Validation规则仍然可能存在问题。

为克服此问题,我使用具有唯一性和存在规则的连接名称。 例如 // connection应该是数据库连接的名称,例如mysql和mysql_new(在我的情况下)

'name' => 'required|unique:connection.users,name',
'email' => 'required|exist:connection.users,email',

我希望它能帮助所有其他想要看起来像这样的开发人员。 对不起我的英语,因为我不是语法专家。