ThinkPHP6多库切换需严格预定义connections、显式链式调用、静态模型绑定且连接名仅限小写加下划线;TP5则配置松散、支持运行时传数组和动态模型切换。

ThinkPHP5 和 ThinkPHP6 在多数据库切换的写法上,核心思路相似(都靠 Db::connect() 指定连接),但配置结构、调用约束和模型绑定机制有实质性差异。不注意这些区别,很容易在迁移或混用时连错库、报错或静默失效。
配置文件位置与结构不同
TP5 多库配置较松散:默认库写在 config/database.php,额外连接可单独定义在 config.php 或其他配置文件中(如 'DB_Config_1' => [...] ),框架会自动合并加载。
TP6 强制统一入口:所有连接必须集中定义在 config/database.php 的 'connections' 数组内,键名为连接标识(如 'user'、'log_db'),'default' 仅作未显式指定时的 fallback,不参与多库逻辑。
- TP5 允许运行时传数组进
Db::connect(['type'=>'sqlite',...])创建临时连接 - TP6 不支持该用法(除非显式传数组,但不属于“配置多库”范畴);所有正式连接必须预定义在
connections中 - .env 文件在 TP6 中无法定义多维 connections,只能覆盖扁平字段(如
DATABASE_HOSTNAME),多库仍需硬编码到 PHP 配置里
Db::connect() 的使用方式更严格
TP5 中 Db::connect('DB_Config_1')->name('test')->select() 可以工作,链式中断容忍度较高;即使漏掉链式调用,有时也能勉强走通(依赖上下文缓存)。
立即学习“PHP免费学习笔记(深入)”;
TP6 要求“显式调用 + 立即链式”:每次 Db::connect('log_db') 返回的是全新 Query 实例,不赋值或不紧跟操作就会丢失上下文。
- 错误写法:
Db::connect('log_db'); Db::name('event')->select();→ 第二行仍走 default - 正确写法:
Db::connect('log_db')->table('event')->select();或$db = Db::connect('log_db'); $db->table('event')->select(); - TP6 中
->name()易出错:它会拼接全局 prefix,跨库时 prefix 常为空,导致表名误解析;推荐统一用->table('db_name.table')或纯表名 + 独立连接
模型类绑定连接的方式和时机不同
TP5 模型可通过构造参数或运行时方法切换连接,灵活性高但易混乱;例如 UserModel::connect('DB_Config_1')->select() 是可行的。
TP6 模型绑定完全静态化:必须在类中声明 protected $connection = 'log_db';,且该值仅在模型类首次初始化时读取一次,运行时修改配置不会自动同步。
- TP6 的
$connection必须与connections数组中的键**完全一致**(大小写敏感),'LogDb'或'log-db'都会静默回退到 default - TP5 支持在控制器中用
Db::connect('xxx')临时切换,TP6 同样支持,但模型内部的with()关联查询不会自动路由到被关联模型的连接,仍走当前模型的$connection - TP6 不支持事务跨连接:两个
Db::connect('a')->startTrans()和Db::connect('b')->startTrans()完全隔离,无法合并提交
连接名命名与校验规则更严格
TP5 对连接名限制较宽松,支持大写字母、点号等(如 'Admin.DB'),只要能被 PHP 数组访问即可。
TP6 明确规定连接名只能是小写字母 + 下划线,否则直接抛异常 Connection not found。
- 合法:
'mysql_read'、'log_db' - 非法:
'log.db'(含点号)、'LogDB'(含大写)、'2nd_db'(数字开头) - 每个连接块必须包含
'type'字段(如'mysql'),漏掉会导致驱动加载失败,报Class 'PDO' not found



















