Laravel 5.4多租户迁移,切换迁移连接

时间:2017-06-14 17:07:28

标签: php laravel laravel-5.4 multi-tenant

我有一个多租户应用,它有一个带有客户端信息的主数据库,它有不同数据库的设置。通过在启动时读取URL,我可以找出他们正在访问的租户,然后切换连接并缓存设置,以便它使用正确的租户数据库。这部分有效,但问题出现在迁移中。

常规Laravel迁移仅处理主表,因此我为“租户”添加了一个迁移文件夹,这需要在每次更新的所有租户上运行。为此,我使用以下类

<?php

namespace App\Console\Commands\Tenants;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;

class UpdateTenant extends Command
{
    protected $signature = 'tenant:update {slug}';
    protected $description = 'Update a tenants database';
    protected $migrator;

    public function __construct()
    {
        parent::__construct();

        $this->migrator =  app()->make('migrator');
    }

    public function fire()
    {
        $arguments = $this->arguments();

        if ($account = DB::connection('root')->table('accounts')->where('slug', '=', $arguments['slug'])->first()) {
            config()->set('database.connections.tenant.database', $arguments['slug']);
            $this->migrator->setConnection('tenant');
            if (! $this->migrator->repositoryExists()) {
                $this->call('migrate:install', ['--database' => 'tenant']);
            }
            $this->migrator->run([$this->laravel->basePath() . '/' . 'database/tenants']);
            foreach ($this->migrator->getNotes() as $note) {
                $this->output->writeln($note);
            }
        }
    }
}

正如你所看到的那样,这只是一个由slug定义的租户,我有另一个命令来循环并调用所有租户的artisan命令。

foreach ($accounts as $account) {
   $this->call('tenant:update', ['slug' => $account->slug]);
}

这里的问题是虽然检查slug的值是正确找到正确的租户信息,但是尽管切换了连接,连接仍然卡在第一个租户上。即使我尝试将其切换到root并返回它,也只是忽略了对配置的更改。 有没有告诉laravel重置连接,以便它将使用配置中的更新值重新连接?

1 个答案:

答案 0 :(得分:2)

通过以下方式断开租户之间的当前连接:

config()->set('database.connections.tenant.database', $arguments['slug']); 
DB::disconnect('tenant');<----- add this
$this->migrator->setConnection('tenant');

这将清理资源连接并强制应用程序使用正确的配置设置重新建立自己。