ThinkPHP多数据库配置必须在config/database.php的connections数组中完整定义每个连接,缺一不可的字段包括type、hostname、database、username、password;连接名仅支持小写字母和下划线,且Db::connect()调用必须链式执行,模型需通过protected $connection显式绑定,否则静默回退default。

ThinkPHP 多数据库配置不是“加几个数组就行”,connections 数组里漏一个 type 或拼错连接名,就会静默 fallback 到 default,查的其实是主库——你根本意识不到数据没走对库。
connections 数组必须填全哪些字段
每个连接(比如 'log_db')在 config/database.php 的 connections 里,以下字段缺一不可:
-
type:必须是mysql、pgsql、sqlsrv等合法驱动名,写成'MySQL'或漏掉直接报Class 'PDO' not found -
hostname:不能是空字符串或未定义变量,env('DB_HOST')要配好,默认值建议写'127.0.0.1' -
database:库名必须真实存在,大小写敏感;同一台 MySQL 上不同库是合法的,但写错就连到空库或权限拒绝 -
username和password:不能留空(除非 MySQL 允许空密码),且不能含未 urlencode 的特殊字符(如@、/) -
hostport:显式写上更稳,别依赖默认 3306,尤其跨服务器时
其他如 charset、prefix 建议也显式设,prefix 强烈设为空字符串(''),避免跨库时表名被错误拼接。
连接名命名规则和常见报错
连接名(connections 数组的 key)不是随便起的,它会直接传给 Db::connect('xxx'),框架校验极严:
立即学习“PHP免费学习笔记(深入)”;
- 只允许小写字母 + 下划线,例如
mysql_slave✅,log.db❌(点号)、AdminDb❌(大写)、2nd_db❌(数字开头) - 拼写必须和
Db::connect()里传的一模一样,大小写敏感;写成'LogDb'就抛Connection not found: LogDb -
default只影响未指定连接时的兜底行为,不参与多库逻辑;删掉它或改名不影响Db::connect('xxx')调用
最隐蔽的坑:你以为写了 Db::connect('log_db') 就切过去了,但如果下一行是 Db::table('event')->select()(没链式),那还是走 default——Db 是无状态门面,不链式调用等于白写。
模型绑定连接的硬性要求
模型类想固定走某库,不能靠猜测或继承,必须显式声明:
- 在模型类里写
protected $connection = 'log_db';,这个值在类加载时读取一次,运行中 reload 配置不会刷新 -
$connection值必须和connections数组里的键**完全一致**,包括大小写;写成'LOG_DB'就静默回退到default - 关联查询(
with())不会自动跨模型切换连接:A 模型绑了log_db,B 模型绑了slave_db,A::with('b')->find()会分别连两个库查,再 PHP 合并——框架不做跨库 JOIN - 多应用模式下(
app_multi => true),每个应用的database.php是独立文件,$connection = 'log_db'只在当前应用生效,不能跨应用复用同一个连接名
临时连接和 .env 分离的实操边界
运行时临时连一个未预定义的库,可以用 Db::connect($array),但要注意它的代价:
- 传数组方式(如
['type'=>'mysql', 'hostname'=>'...'])不走连接池,高并发下容易触发 MySQL 的Too many connections - DSN 字符串方式(
mysql://user:pass@host:port/db#utf8mb4)适合快速测试,但特殊字符必须urlencode(),否则解析失败 - .env 文件里不能用
DATABASE2.HOSTNAME这种嵌套写法,TP6 不识别;正确做法是在config/database.php中用env('DB2_HOST', '127.0.0.1')拉取,然后在connections里按需组装 - 改完
database.php必须执行php think clear:config,否则缓存导致新配置不生效
真正难的不是写配置,而是理解「连接名即契约」——它既是配置里的 key,又是代码里的字面量,还是异常信息里的字符串。这三个地方对不上,问题就藏在日志底下,等你花半天时间怀疑是不是 SQL 写错了。



















