.env 是 ci4 读取数据库配置的首选位置,因其支持环境隔离、敏感信息保护及自动注入机制;直接修改 database.php 会绕过该机制,导致环境混淆与安全风险。

.env 文件是 CI4 读取数据库配置的首选位置,不是 app/Config/Database.php —— 后者只在 .env 缺失或未启用时才兜底生效。直接改 PHP 配置文件反而容易被忽略、覆盖或误提交。
为什么必须用 .env 而不是硬编码在 PHP 文件里
CI4 的 DotEnv 加载机制默认在 public/index.php 开头就解析 .env,所有 database.default.* 类配置项都会被自动注入到 Config 对象中。如果你跳过这步,直接在 Database.php 里写死参数,那你就绕过了环境隔离逻辑,本地开发和线上生产会共用同一套值,出问题很难定位。
-
.env支持#注释、空行、引号包裹(含空格或特殊字符的密码) - Git 默认应忽略
.env,避免密钥泄露;而Database.php是代码文件,不该存敏感信息 - CI4 的
Config\Database类内部会优先调用getenv()查找database.default.hostname这类键,找不到才 fallback 到数组默认值
.env 中数据库配置的写法和常见错误
正确格式必须严格匹配 CI4 的命名规范,大小写、点号、等号前后空格都不能错:
database.default.hostname = "localhost" database.default.database = "yourusername_myapp_db" database.default.username = "yourusername_myapp_user" database.default.password = "P@ssw0rd!2026" database.default.DBDriver = "MySQLi" database.default.port = "3306"
- 驱动名必须是
MySQLi(首字母大写 M 和 i),不是mysqli或mysql,否则加载失败且无明确报错 - 密码含特殊字符时一定要用双引号包裹,否则
!、$等会被 shell 解析为变量或命令 - 如果主机不是
localhost(比如 Namecheap 共享主机有时要求填127.0.0.1),请实测确认,localhost在某些 MySQL 配置下会走 socket 而非 TCP,导致权限拒绝 -
database.default.port不写默认是 3306,但显式写出更利于排查防火墙或云数据库限制
如何验证 .env 配置是否生效
别只信日志或白屏,用最直白的方式确认 CI4 真正读到了你写的值:
- 在控制器里加一行:
var_dump(config('Database')->default);,看输出的数组里字段是否和.env一致 - 故意把
database.default.database写错,访问页面时若报Database: Unable to connect to your database server using the provided settings.,说明 CI4 正在读它;如果没报错或报错是别的内容(比如类找不到),说明.env根本没加载 - 检查
public/index.php开头是否有DotEnv::createImmutable(...)调用,没有的话手动补上(CI4.5+ 默认有,老版本可能漏) - 确认
.env文件权限是 644,且位于项目根目录(即和app/、public/同级),不是放在public/下
部署到共享主机(如 Namecheap)时的特殊处理
Namecheap 的 cPanel 数据库用户名和库名强制带前缀,这个细节极易被忽略,而且错误信息不提示:
- 你在 cPanel「MySQL Databases」里看到的数据库名是
youruser_mydb,不是mydb;同理用户是youruser_myuser - 即使你用 phpMyAdmin 登录成功,也不代表 CI4 能连——因为 phpMyAdmin 可能用了不同用户或 host 权限
- 务必去 cPanel 的「Add User to Database」页面,把用户和库手动关联,并勾选
ALL PRIVILEGES,仅创建用户不授权等于没建 - 如果仍连不上,先写个裸 PHP 测试脚本(用
mysqli_connect()),排除是主机限制还是 CI4 配置问题











