ThinkPHP6 如何配置多数据库连接并实现动态切换?
ThinkPHP 6.1+ 通过 Db::setConnectConfig() 方法支持运行时动态注册连接配置,但 hostport 必须为整数 3306,字符串"3306"会导致连接静默失效。
原因分析
ThinkPHP 6 的连接管理基于「连接标识 + 连接池」机制,而非每次查询都新建连接。直接调用 Db::connect(['hostname' => 'xxx']) 确实能创建新连接,但这个连接不会自动注入到当前请求的查询链路中——后续所有 Db::table()、Model::find() 仍走默认连接。这不是 bug,是设计使然。多租户场景下,需在应用启动早期(如中间件)完成连接注册与全局绑定,避免在控制器里反复调用 Db::connect() 并试图"覆盖"默认连接。
解决方案
方案一:预定义多库配置(推荐静态场景)
在 config/database.php 的 connections 数组中预定义多个连接键名:
return [
'default' => 'mysql',
'connections' => [
'mysql' => [
'type' => 'mysql',
'hostname' => '192.168.1.10',
'database' => 'main_db',
'username' => 'app_rw',
'password' => 'xxx',
'hostport' => 3306,
'charset' => 'utf8mb4',
],
'log_db' => [
'type' => 'mysql',
'hostname' => '192.168.1.11',
'database' => 'log_db',
'username' => 'app_ro',
'password' => 'yyy',
'hostport' => 3306,
'charset' => 'utf8mb4',
],
],
];使用时调用 Db::connect('log_db')->table('user')->select(),注意每次查询都要显式调用 connect()。
方案二:运行时动态注册(多租户场景)
ThinkPHP 6.1+ 提供 Db::setConnectConfig() 方法,允许在运行时注册带标识的新连接配置:
// 在全局中间件中解析租户标识
$tenantId = 'tenant_123';
$config = [
'type' => 'mysql',
'hostname' => '127.0.0.1',
'database' => 'db_' . $tenantId,
'username' => 'root',
'password' => 'root',
'hostport' => 3306,
];
Db::setConnectConfig($tenantId, $config);
// 查询时显式指定
Db::name('user')->connect($tenantId)->select();这是目前最稳妥的动态方案,避免为上千租户预定义完整连接配置数组。
方案三:模型固定绑定
在模型类顶部加 protected $connection = 'log_db'; 即可绑定非默认库,比每次手动 connect() 更稳妥。这个值对应配置文件里的键名,不是 DSN 或 host。
注意事项
1. hostport 必须是整数,"3306"会静默失效,错误信息通常是 PDOException: SQLSTATE[HY000] [1045] 或直接超时。
2. 连接名含点号(如'log.db')或大写字母,Db::connect() 直接抛出 Connection not found: log.db。
3. 事务不跨库,$db1->startTrans() 和 $db2->startTrans() 是两个孤立事务,无法合并提交或回滚。强行混用会导致部分写入成功、部分失败,数据不一致。
4. 在循环里反复调用 Db::connect(['hostname' => ]),每次新建连接不复用,高并发下 MySQL 报 Too many connections。
5. 配置中'database' => 'my_app_v2'大小写敏感(尤其 Linux 环境),漏了 database 项会报错"No database selected"。
6. 模型 $connection 只影响该模型的主表操作,with() 关联查询时关联模型仍走自己的$connection,不会跨库 join。
参考来源
来源:CSDN 博客 - ThinkPHP6 多数据库连接配置及动态切换实践(2026 年 4 月 20 日)
来源:看云 - ThinkPHP6.0 完全开发手册 连接数据库章节(2025 年 4 月 22 日)
来源:博客园 - ThinkPHP 6 连接配置多个数据库并实现自由切换详细过程(2026 年 4 月 16 日)
来源:知乎专栏 - ThinkPHP 动态指定连接库操作指南(2026 年 3 月 30 日)