thinkphp5连接多个数据库必须通过config/database.php的connections数组预定义键名,键名须小写无点号、每个连接显式声明type及完整参数,db::connect()仅接受该键名字符串调用,否则高并发易出错。

ThinkPHP5 连接多个数据库,必须通过 config/database.php 的 connections 数组预定义连接键名,不能靠传数组或 DSN 临时拼凑——否则高并发下会触发 Too many connections 或连错库。
在 database.php 中正确定义多个命名连接
这是唯一推荐用于生产环境的方式。框架只从 connections 数组里读取配置,键名必须小写、无点号、无大写字母,且每个连接必须显式声明 type 字段。
-
type值必须准确,如mysql、pgsql,写错会导致Class 'PDO' not found(实际是 PDO 扩展未启用或驱动不匹配) - 所有必要字段(
hostname、database、username、password)一个都不能省,空字符串也不行 - 键名示例:
mysql_master✅,log.db❌(含点号),LogDB❌(大小写敏感) - 改完后必须执行
php think clear:config,否则缓存导致新配置不生效
用 Db::connect() 正确加载指定连接
Db::connect() 只接受已预定义的键名字符串,不是数据库名、不是模型名、更不是配置数组。
- 调用方式:
Db::connect('mysql_slave')->table('log')->select(),其中mysql_slave必须已在connections中完整定义 - 若抛出
Connection not found: mysql_slave,先检查键名拼写,再确认是否漏清配置缓存 - 禁止在循环或高频接口中传配置数组:
Db::connect(['hostname' => '...'])—— 每次新建 PDO 实例,不走连接池,MySQL 很快报错 - 模型内绑定连接用
protected $connection = 'log_db',但注意:关联查询(如with('profile'))仍走Profile模型自己的$connection,不会跨库自动合并
用 .env 实现多库参数环境隔离
.env 文件不支持嵌套或数组语法,只能提供扁平变量,需手动拼接到 connections 配置中。
- 正确写法:
database2_hostname=192.168.1.11,然后在database.php中写'hostname' => env('database2_hostname', '127.0.0.1') - 错误写法:
DATABASE2[HOSTNAME]=...或database2.host=...——.env解析器直接忽略 - 所有数据库地址、端口、账号密码都应通过
env()注入,避免配置文件提交到 Git 泄露凭据 - 如果用了
read_master做读写分离,记得在database.php显式读取:'read_master' => env('READ_MASTER', false),否则该开关永远为false
跨库查询必须手动分查 + PHP 层合并
MySQL 本身不支持跨实例 JOIN,ThinkPHP 也不会帮你把两个库的数据“智能组装”。所谓“关联查询”只是同库表间操作。
- 别指望
User::with('login_log')->select()能自动从主库和日志库各取一部分再拼起来 - 真实做法:先查用户列表 → 提取 ID 数组 → 再用
Db::connect('log_db')->where('user_id', 'in', [...])->select()批量查日志 → 最后用 PHP 关联两个数组 - 注意字段名冲突:两个库都有
id字段时,查日志要显式重命名,比如->field('id as log_id, user_id, content'),否则 PHP 合并时会被覆盖 - 事务中所有查询强制走主库,哪怕你写了
Db::connect('slave_db')也没用 —— TP5.0–5.1 的路由逻辑只认事务状态和上一条 SQL 类型
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











