ThinkPHP5多库连接必须预定义connections键名,禁止传数组/DSN或非法命名;.env不支持嵌套,需手动拼接;跨库查询需手动分查合并,且须核对各连接地址避免写混。

ThinkPHP5 支持多数据库连接,但必须通过 config/database.php 的 connections 数组预定义键名;直接传数组或 DSN 到 Db::connect() 虽能跑通,但高并发下极易触发 Too many connections 或连错库,不推荐用于生产。
Db::connect() 只认 config/database.php 里的 connections 键名
框架内部只从 connections 数组中查找连接配置,传入的字符串必须是该数组中存在的键(如 'log_db'),不能是点号、大写、路径式命名(如 'db.log' 或 'LogDB'),否则抛出 Connection not found。
-
Db::connect('mysql2')✅ —— 前提是connections['mysql2']已完整定义 -
Db::connect(['hostname' => '127.0.0.1'])❌ —— 每次新建 PDO 实例,不复用连接池,压测时 MySQL 很快报Too many connections -
Db::connect('log.db')❌ —— 键名含点号,框架解析失败 -
Db::connect('LogDB')❌ —— 键名大小写敏感,connections里若定义的是'logdb',就匹配不上
.env 无法定义多库结构,只能扁平覆盖
.env 文件不支持嵌套或数组语法,所以像 DATABASE2.HOSTNAME 这类写法无效。它只能提供一级变量,比如 database2_hostname=192.168.1.11,然后在 database.php 中用 env('database2_hostname') 手动拼接进 connections 配置里。
- 错误写法:
DATABASE2[HOSTNAME]=192.168.1.11(.env不识别方括号语法) - 正确写法:
database2_hostname=192.168.1.11,再在 PHP 配置中引用env('database2_hostname') - 漏写
'type' => 'mysql'会导致框架用默认驱动去解析 PostgreSQL 配置,报错Class 'PDO' not found(实际是扩展未启用)
跨库查询必须手动合并,TP 不做自动 join
MySQL 本身不支持跨实例 JOIN,ThinkPHP 也不会帮你把两个库的数据“智能合并”。模型设置 protected $connection = 'log_db' 只影响本模型主表操作;with('profile') 仍会按 Profile 模型自己的 $connection 去查,不会跨库拉数据。
立即学习“PHP免费学习笔记(深入)”;
- 别指望
User::with('login_log')->select()自动从main_db和log_db各取一部分再组装 - 真实做法:先查用户
Db::connect('mysql')->table('user')->where(...)->select(),再用 ID 批量查日志Db::connect('log_db')->table('login_log')->where('user_id', 'in', [...])->select(),最后 PHP 层关联 - 注意字段名冲突:两个库同名字段(如都叫
id)合并时需显式重命名,避免覆盖
最易被忽略的一点:复制粘贴配置后,常只改了 database 名,却忘了同步修改 hostname 或 port,结果多个连接全指向同一台 MySQL 实例,数据写混、权限错乱、排查困难——配完务必逐项核对每个连接的完整地址和凭据。



















