插件窝 干货文章 如何在 Laravel 多租户扩展 stancl/tenancy 中自定义租户数据库主机?

如何在 Laravel 多租户扩展 stancl/tenancy 中自定义租户数据库主机?

租户 数据库 tenant tenancy 287    来源:    2025-03-14

在 Laravel 中使用 stancl/tenancy 扩展实现多租户时,默认情况下,每个租户的数据库连接信息(如数据库名称、用户名、密码等)是存储在 tenants 表中的。然而,stancl/tenancy 默认不支持直接为每个租户指定自定义的数据库主机(即数据库服务器地址)。不过,你可以通过自定义数据库连接来实现这一需求。

以下是如何在 stancl/tenancy 中自定义租户数据库主机的步骤:

1. 修改 tenants 表结构

首先,你需要在 tenants 表中添加一个 database_host 字段,用于存储每个租户的数据库主机地址。

Schema::table('tenants', function (Blueprint $table) {
    $table->string('database_host')->nullable();
});

2. 自定义数据库连接

接下来,你需要自定义数据库连接逻辑,以便在租户切换时使用自定义的数据库主机。

App\Providers\TenancyServiceProvider 中,你可以覆盖 boot 方法,并在其中定义自定义的数据库连接逻辑。

use Stancl\Tenancy\Tenancy;
use Stancl\Tenancy\Database\DatabaseManager;
use Illuminate\Support\Facades\DB;

class TenancyServiceProvider extends \Stancl\Tenancy\Providers\TenancyServiceProvider
{
    public function boot()
    {
        parent::boot();

        // 监听租户切换事件
        Tenancy::hook('bootstrapped', function (Tenancy $tenancy) {
            $tenant = $tenancy->tenant;

            // 获取租户的数据库主机
            $databaseHost = $tenant->database_host;

            // 自定义数据库连接
            config([
                'database.connections.tenant.host' => $databaseHost,
            ]);

            // 重新连接数据库
            DB::purge('tenant');
            DB::reconnect('tenant');
        });
    }
}

3. 配置租户数据库连接

config/database.php 中,确保你已经定义了 tenant 连接。你可以基于 mysql 连接进行配置:

'tenant' => [
    'driver' => 'mysql',
    'host' => env('DB_TENANT_HOST', '127.0.0.1'),
    'port' => env('DB_TENANT_PORT', '3306'),
    'database' => env('DB_TENANT_DATABASE', 'forge'),
    'username' => env('DB_TENANT_USERNAME', 'forge'),
    'password' => env('DB_TENANT_PASSWORD', ''),
    'unix_socket' => env('DB_TENANT_SOCKET', ''),
    'charset' => 'utf8mb4',
    'collation' => 'utf8mb4_unicode_ci',
    'prefix' => '',
    'strict' => true,
    'engine' => null,
],

4. 在租户创建时设置数据库主机

当创建新租户时,确保你设置了 database_host 字段:

$tenant = Tenant::create([
    'id' => 'tenant1',
    'database_host' => 'custom-db-host.example.com',
    // 其他字段...
]);

5. 测试

现在,当你切换到某个租户时,stancl/tenancy 会自动使用该租户的 database_host 来连接数据库。

总结

通过以上步骤,你可以在 stancl/tenancy 中为每个租户自定义数据库主机。这种方法允许你在多租户环境中灵活地管理不同租户的数据库连接信息。