ThinkPHP数据库配置生效关键在default、connections等顶层键名,.env变量须用env()函数读取并设默认值,SSL参数需用PDO常量且路径为绝对路径,多库切换时连接名必须与connections键完全一致。

ThinkPHP 的数据库连接不是“填完就跑”,关键在 database.php 里哪些配置生效、哪些被忽略、哪些必须用环境变量兜底——尤其在多环境部署时,硬编码密码或主机名会直接导致上线失败。
database.php 中真正起作用的顶层键名只有这几个
ThinkPHP 6+ 的数据库配置结构是扁平化 + connections 嵌套双模式,但你写的每一项都得落在框架识别的 key 上,否则静默失效:
-
default:字符串,必须是connections数组里的某个键名(如'user'),不能写成'mysql'或空字符串 -
connections:必须是关联数组,每个子项代表一个独立连接,键名将作为后续Db::connect('xxx')的参数 -
fetch_sql、debug、deploy这类开关型配置,只在顶层写才全局生效;放在某个 connection 里会被忽略 -
params是唯一能透传 PDO 底层参数的地方(比如 SSL、超时、持久连接),别试图往dsn字符串里拼接
密码和敏感信息必须从 .env 读,不能直接写死在 database.php 里
硬编码密码在 Git 提交后等于公开数据库权限。ThinkPHP 支持 env() 函数自动读取 .env 文件,且优先级高于配置文件本身:
- 在
.env中写:DATABASE_USERNAME=root、DATABASE_PASSWORD=123456 - 在
database.php中对应位置写:'username' => env('DATABASE_USERNAME', 'root') - 注意:env() 第二个参数是 fallback,默认值仅用于本地开发,生产环境必须靠 .env 覆盖
- 如果
.env文件没加载(比如 CLI 模式下未调用think\Env::load()),env() 会返回 null,导致连接报错SQLSTATE[HY000] [1045] Access denied
SSL 连接只能通过 params 数组配置,且路径必须是绝对路径
MySQL 启用 SSL 不是加个开关就行,ThinkPHP 只负责把参数原样交给 PDO。常见错误是把证书路径写成相对路径或 URL:
立即学习“PHP免费学习笔记(深入)”;
- 正确写法:
PDO::MYSQL_ATTR_SSL_CA => '/etc/mysql/ssl/ca.pem'(绝对路径,PHP 进程有读权限) - 错误写法:
'ssl_ca' => './certs/ca.pem'(相对路径,PDO 找不到文件) - 若服务端要求双向认证,还需同时提供
PDO::MYSQL_ATTR_SSL_CERT和PDO::MYSQL_ATTR_SSL_KEY,且私钥不能设密码 - SSL 模式必须用整数常量:
PDO::MYSQL_ATTR_SSL_MODE_REQUIRED,不能写字符串'REQUIRED',否则被忽略
多数据库切换时,connection 键名和模型绑定要对得上
定义了多个 connection 后,实际使用时容易混淆“谁连谁”:
- 手动切换:
Db::connect('admin')->table('users')->select(),这里'admin'必须和connections数组的键完全一致(区分大小写) - 模型绑定:
protected $connection = 'admin';,这个字符串也必须匹配 connections 键名,不能是数据库名或 DSN - 切记:模型里写
$connection = 'mysql',但 config 中 connections 键是'user',那就永远连不上 - 调试技巧:执行
Db::connect('xxx')后 dump 返回值,看config['database']是否是你预期的库名
最易被忽略的是 params 的键名必须是 PDO 常量,而不是字符串;以及 .env 在 CLI 环境下默认不加载——这两点一旦出错,日志里不会提示配置问题,只会报“连接被拒绝”或“SSL handshake failed”,排查方向容易跑偏。



















