【问题标题】:Laravel one domain, multiple database detected by SessionLaravel 一个域,Session 检测到多个数据库
【发布时间】:2019-04-29 18:13:51
【问题描述】:

我已经阅读了几篇关于 SaaS、多租户等主题的帖子/主题(如 thisthisthis),我得出的结论是其中大多数不符合我的要求:

  1. 我不需要多租户,因为我只会使用主域
  2. 我无法在 .env 或 database.config 中写入我的所有 MySQL 连接,因为它们都是动态的(至少是数据库的名称)

我需要的工作流程

  1. 订阅 (SaaS) 包含数据库名称
  2. 每当用户登录时,都会为他的会话分配数据库名称
  3. 对用户数据库运行所有查询

例子:

- project_admin <- Main database 
--- subscriptions <- Table
------ id | db_name
------ 1  | project_child_one
------ 2  | project_child_two
--- users <- Table
------ id | subscription_id 
------ 1  | 1 
------ 2  | 2

- project_child_one <- Child database
--- customers <- table

- project_child_two <- Child database
--- customers <- table
  • user 1登录时,从客户那里检索到的数据应该来自数据库project_child_one
  • user 2登录时,从客户那里检索到的数据应该来自数据库project_child_two

我希望将数据库名称保存在会话中,因此我不需要总是查询project_admin 来了解用户应该连接到哪个数据库。这是最简单的部分。

【问题讨论】:

  • 不要在会话中存储数据库连接设置。相反,如果您必须拥有多个数据库,请考虑使用中间件根据经过身份验证的用户动态设置连接。
  • @MartinBean 我不会在会话中存储连接设置,只存储数据库名称。我还没有弄清楚如何通过这种方法使用中间件?

标签: php mysql laravel


【解决方案1】:

如果你真的需要一个“租户”数据库连接,那么你可以在中间件类中动态配置它:

class ConfigureTenantConnection
{
    public function handle($request, Closure $next)
    {
        if ($user = $request->user()) {
            // Create a tenant database connection if there is an authenticated user
            config([
                'database.connections.tenant' => [
                    'driver' => 'mysql',
                    // I don’t know what column names you use, but…
                    'host' => $user->database_host,
                    'port' => $user->database_port,
                    'database' => $user->database_name,
                    'username' => $user->database_username,
                    'password' => $user->database_password,
                ],
            ]);
        }

        return $next($request);
    }
}

然后您可以在数据库查询和模型中使用此tenant 连接:

abstract class TenantModel extends Model
{
    protected $connection = 'tenant';
}

class Widget extends TenantModel
{
    protected $table = 'widgets';
}

【讨论】:

【解决方案2】:

嗯,我不确定这是否是您的意思。 但是,如果您希望数据库名称是动态的,您可以在 laravel 中轻松地进行如下操作。配置的连接部分应该像上面那样。但是,您可以在运行时在控制器上更改数据库凭据。 如果我们以上面的示例进行配置,那么 .你可以在控制器上这样做。

    $config= [
            'database'=>'Dynamic db name',
    ];
    Config::set("database.connections.mysql2",$config);
    DB::purge('mysql');
    DB::setDefaultConnection('mysql2');

假设您想在事务后切换另一个数据库,您可以这样做

     $config= [
            'database'=>'Dynamic db name',
    ];
    Config::set("database.connections.mysql",$config);
    DB::purge('mysql2');
    DB::setDefaultConnection('mysql2');

希望对你有帮助

【讨论】:

  • 更多信息可以在here找到。
  • 我不想在控制器中这样做。我需要它在模型中或以某种方式注入到中间件中。
猜你喜欢
  • 2021-11-17
  • 1970-01-01
  • 1970-01-01
  • 2018-03-28
  • 2018-08-09
  • 2013-06-01
  • 2020-01-28
  • 1970-01-01
  • 2020-04-10
相关资源
最近更新 更多