最可靠的做法是直接在项目根目录的 .env 文件中配置数据库,以 database.default. 开头,如 database.default.hostname = "localhost",且需确保文件存在、权限为 644、putenv() 可用,并注意 DBDriver 大写、特殊字符用双引号包裹。

直接在 .env 里写数据库配置最可靠
CI4 默认优先读取 .env 文件,而不是 app/Config/Database.php。如果你改了 Database.php 却没生效,大概率是 .env 里的配置覆盖了它——而且你可能根本没启用 .env(比如本地开发时忘了去掉 phpdotenv 的注释,或生产环境被服务器禁用了 putenv())。
正确做法是:确保项目根目录存在 .env 文件,并且内容以 database.default. 开头,例如:
database.default.hostname = "localhost" database.default.database = "yourusername_mydb" database.default.username = "yourusername_dbuser" database.default.password = "s3cureP@ss!2026" database.default.DBDriver = "MySQLi"
-
DBDriver必须大写,且值要匹配实际扩展,常见的是"MySQLi"或"Postgre",不是"mysql"或"pdo" - 密码含特殊字符(如
!、@、$)必须用双引号包裹,否则会被解析失败 - 如果主机商强制要求端口(比如 Namecheap 的 MySQL 有时走非标准端口),得加一行:
database.default.port = "3306"
为什么 .env 配置不生效?常见断点在这儿
不是写了就管用。CI4 启动时会按顺序加载:先读 .env → 再初始化 Config/Database.php → 最后才实例化连接。中间任一环节出错,.env 就白写了。
- 文件名必须是
.env(开头带点),不能叫env、.env.example或config.env - Apache 或 Nginx 没开
AllowOverride All,导致.htaccess里重写规则失效,index.php没被正确路由,.env根本没机会加载 - cPanel 或共享主机禁用了
putenv()函数,CI4 就无法把.env变量注入 PHP 环境 —— 此时只能退回到硬编码到app/Config/Database.php中 -
.env文件权限设成了600或更严,Web 服务器用户(如nobody或apache)读不了,得改成644
.env 和 Database.php 的优先级关系
CI4 的设计是:所有 database.* 配置项,.env 优先于 Database.php;但 Database.php 里定义的非数据库字段(比如自定义的 $db['default']['some_custom_option'])不会被 .env 覆盖,也不会自动映射过去。
- 如果你想保留
Database.php里的某些逻辑(比如动态判断环境切换 host),就别全删掉,而是让.env只管基础四要素:hostname、username、password、database -
DBDriver、port、charset这类可选参数,建议统一放在.env,避免Database.php里写死导致环境迁移困难 - 如果用了多组连接(比如
database.reporting.),每组都得在.env里完整声明,不能只写一部分
测试 .env 是否真被读取了
别靠猜。最直接的办法是临时在 app/Config/Database.php 的构造函数或 init() 方法里加一句 error_log('DB config loaded: ' . env('database.default.username'));,然后看 PHP 错误日志有没有输出。
或者更简单:在控制器里写一行调试代码:
dd(env('database.default.database'));
- 如果返回
null或空字符串,说明.env没加载成功,回头查文件位置、权限、putenv()是否可用 - 如果返回了预期值,但数据库还是连不上,问题就在连接参数本身(比如用户名拼错、权限没绑、数据库名格式不对——Namecheap 要求是
username_dbname形式) - 注意:
dd()是 CI4 的调试函数,仅在development环境下有效;生产环境请改用log_message('debug', ...)


















