thinkphp6不支持自动识别多库或运行时动态注册连接,必须在config/database.php的connections数组中提前完整定义所有连接(含type、hostname、database、username、password),连接名仅限小写字母和下划线,模型需显式指定$connection属性,db::connect()返回新实例且不改变默认连接,事务与join天然不跨库。

直接说结论:ThinkPHP6不支持“自动识别多个数据库”或“运行时动态注册连接”,必须在config/database.php的connections数组里**提前定义好所有连接名和完整配置**,再通过Db::connect('name')或模型protected $connection = 'name'显式指定——漏掉任一环节,就默认走default库,且不会报错提示。
connections数组必须完整定义每个连接
所有多库配置都得落在config/database.php的connections键下,不能靠.env加编号(如DATABASE2_HOSTNAME)或运行时传数组糊弄过去。
-
type、hostname、database、username、password这5项缺一不可;漏掉type会报Class 'PDO' not found - 连接名只能是小写字母+下划线,比如
log_db合法,log.db或LogDB会直接抛Connection not found -
prefix建议设为空字符串(''),跨库时用table('db_name.table')更可控,避免name('user')自动拼错前缀 -
.env只能覆盖扁平变量(如DB_HOST),无法定义connections这种嵌套结构,多库配置必须写死在database.php里
Db::connect()不是“切换”,而是新建实例
Db::connect('log_db')返回的是一个全新的Query对象,它不改变全局默认连接,也不影响后续未显式调用的Db::table()或Model::find()。
- 错误写法:
Db::connect('log_db'); Db::table('event')->select();→ 第二行仍走default - 正确写法:
Db::connect('log_db')->table('event')->select();或先赋值:$logDb = Db::connect('log_db');,再用$logDb->table() - 链式中慎用
->cache()、->useSoftDelete()等中间方法,它们可能破坏连接上下文,导致意外切回default - 传参必须是
connections里已定义的连接名字符串,不能传模型名、表名或DSN;传错名会直接异常,不静默 fallback
模型类固定绑定连接要靠$connection属性
模型默认永远走default连接,除非你在类里硬编码protected $connection = 'log_db';。这个值只在模型首次加载时读取一次,运行时改配置也不会重新生效。
-
$connection的值必须和connections数组里的键**完全一致**(大小写敏感),写成'LogDb'或'log-db'都会静默 fallback 到default - 该设置只影响当前模型的全部操作(
find、save、delete),不影响关联模型;如果关联模型也要走同库,得在with()或关联定义里显式加'connection' => 'log_db' - 迁移命令
php think migrate:run完全不识别模型的$connection,它只按database.default执行,别指望用模型绑定来跑跨库迁移
最常被忽略的一点:事务和JOIN天然不跨连接。你用Db::connect('a')->startTrans()和Db::connect('b')->startTrans()开的事务完全隔离,没法合并提交;两个不同连接的表也无法直接join,得靠子查询或应用层组装。这不是bug,是设计约束——TP6从没打算让你把多库当单库用。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











