ThinkPHP数据库配置生效的前提是database.php中所有连接参数(如hostname、database等)必须显式调用env()函数并设默认值,否则修改.env文件无效;.env须置于项目根目录、全大写下划线命名、等号无空格,且修改后需执行php think clear:config清除缓存。

env() 函数必须出现在 database.php 里,否则改了 .env 文件完全没用。
为什么改了 .env 数据库配置却连不上
最常见原因是 database.php 没有调用 env() 读取变量,而是直接写死参数。框架不会自动把 .env 中的 DB_HOST 映射到配置文件里的 hostname 字段——你得手动写 'hostname' => env('DB_HOST', '127.0.0.1')。
其他关键点:
-
.env文件必须放在项目根目录(和app/、config/同级),不能放public/或config/下 -
.env中变量名必须全大写 + 下划线,如DB_PORT,不是db_port或DB-PORT - 等号两侧不能有空格:
DB_PASSWORD=123456✅,DB_PASSWORD = 123456❌ - 修改
.env后必须清缓存:php think clear:config,否则旧配置仍生效
database.php 中哪些字段必须用 env() 包裹
所有可能随环境变化的连接参数都该走 env(),尤其是这些:
-
type:数据库类型,如mysql、pgsql,生产环境可能切 PostgreSQL -
hostname和hostport:开发用127.0.0.1,测试/生产常是内网域名或 IP -
database:不同环境库名不同(myapp_dev/myapp_prod) -
username和password:绝对不能硬编码,必须从.env读 -
prefix:有些环境启用了表前缀,有些没启,靠env('DB_PREFIX', '')控制
注意:default 和 connections 是顶层结构键,不参与 env() 替换;但它们内部每个连接的字段都得单独处理。
立即学习“PHP免费学习笔记(深入)”;
SSL 连接失败时 params 怎么配才有效
MySQL 启用 SSL 不是加个开关就行,ThinkPHP 只负责把 params 数组原样传给 PDO。常见报错 SQLSTATE[HY000] [2002] 或静默失败,基本都是路径或常量写错了。
- 证书路径必须是绝对路径,且 PHP 进程有读权限:
PDO::MYSQL_ATTR_SSL_CA => '/etc/mysql/ssl/ca.pem' - 不能写相对路径:
'ssl_ca' => './certs/ca.pem'(PDO 找不到) - SSL 模式必须用整数常量:
PDO::MYSQL_ATTR_SSL_MODE_REQUIRED,不能写字符串'REQUIRED' - 双向认证需同时提供
PDO::MYSQL_ATTR_SSL_CERT和PDO::MYSQL_ATTR_SSL_KEY,私钥不能设密码
这些只能写在某个 connection 的 params 数组里,不能塞进 DSN 字符串,也不能放到顶层配置中。
多数据库连接怎么定义和切换
ThinkPHP 不支持“自动识别多个库”,必须显式命名并预定义。比如主从分离,就得在 connections 里写两个独立项:
return [
'default' => 'mysql_master',
'connections' => [
'mysql_master' => [
'type' => env('DB_MASTER_TYPE', 'mysql'),
'hostname' => env('DB_MASTER_HOST', '127.0.0.1'),
// ... 其他参数
],
'mysql_slave' => [
'type' => env('DB_SLAVE_TYPE', 'mysql'),
'hostname' => env('DB_SLAVE_HOST', '192.168.1.100'),
// ... 其他参数
],
],
];
- 键名必须小写、无特殊字符,如
mysql_slave✅,slave-db❌ - 每个连接都必须带
type,漏掉会报Class 'PDO' not found - 运行时用
Db::connect('mysql_slave')获取只读连接,不是Db::connect('slave') - 模型绑定连接用
$connection = 'mysql_slave'属性,不是字符串'slave'
真正容易被忽略的是:所有连接的 env() fallback 默认值,必须保证本地开发能跑通;而生产环境的 .env 必须覆盖全部敏感字段,否则 env('DB_PASSWORD') 返回 null,直接触发 Access denied。



















