.env 是 codeigniter 4.7.2 唯一推荐的环境配置入口,必须存在且禁止 git 跟踪;它决定 $dotenv 加载、数据库连接、调试开关等核心参数,缺失将导致配置回退默认值,引发环境错配风险。

.env 文件在 CodeIgniter 4.7.2 中是环境配置的唯一推荐入口,不是可选补充——它直接决定 $dotenv 加载行为、数据库连接、调试开关等核心运行时参数。CI4 不再读取 app/Config/ 下的 PHP 配置文件作为“主配置源”,而是把它们当作模板,所有实际值必须由 .env 注入。
为什么 .env 必须存在且不能被 Git 跟踪
CI4.7.2 启动时会强制检查 .env 是否可读(DotEnv::load()),若不存在或权限不足,Services::config() 返回的实例将回退到硬编码默认值(比如数据库 host 是 127.0.0.1,CI_ENVIRONMENT 默认为 production),但不会报错,极易导致本地开发连错测试库、生产环境意外开启 display_errors。
-
.env文件需放在项目根目录(与public/同级),权限设为644,禁止写入 Web 用户(如www-data) - 必须加入
.gitignore:.env、.env.example(后者用于提交示例结构) - CI4.7.2 不支持
.env.local或多层覆盖,只加载第一个找到的.env
CI_ENVIRONMENT 决定配置加载路径和行为
CI_ENVIRONMENT 是整个环境切换的总开关,它不只影响日志级别,还控制 app/Config/ 下哪些类被实例化、哪些 .env 变量被启用:
- 值必须是
development、testing或production—— 其他值(如staging)会被静默转为production,且App类的isDevelopment()判断失效 - 不同环境对应不同数据库配置段:比如
database.default.hostname在development下可指向localhost,而production下必须用db-prod.internal,但变量名完全一致,靠环境隔离 -
app/Config/Logger.php中的$threshold值由CI_ENVIRONMENT自动映射:development→4(DEBUG),production→1(ERROR)
数据库、邮件等服务配置要按环境分段写,不能拼接
CI4.7.2 的 .env 支持用点号分隔的嵌套键,但**不支持变量插值或条件判断**。常见错误是试图写 database.default.hostname = ${DB_HOST} 或 mail.from_email = "admin@${CI_ENVIRONMENT}.example.com" —— 这些全部无效,DotEnv 只做纯字符串替换,不执行 shell 或 PHP 解析。
- 正确写法是显式分环境定义:
database.development.hostname = "localhost"、database.production.hostname = "db-prod.internal",然后在app/Config/Database.php中通过env('database.' . ENVIRONMENT . '.hostname')读取 - 邮件发件人必须全写:
email.from_email = "no-reply@prod.example.com",别指望自动替换成dev域名 - 敏感字段(如
database.default.password)建议留空,改用环境变量注入:database.default.password = "${DB_PASSWORD}",再在服务器上export DB_PASSWORD=xxx—— 注意:这依赖系统 shell,Docker 容器内需在docker run -e中传入
自定义配置项要加前缀避免冲突
CI4.7.2 的 env() 函数全局可用,但如果你在 .env 里写 cache_driver = redis,可能和框架内部的 cache.driver 键冲突(CI4 使用冒号分隔层级,cache:driver 才是标准格式)。更稳妥的做法是统一加业务前缀:
- 用
app.api_base_url = "https://api.dev.example.com",而非api_base_url = ... - 在控制器中读取:
env('app.api_base_url', 'https://api.example.com'),第二个参数是 fallback,默认值 - 不要复用 CI4 内置键名(如
app.baseURL、database.default.DBDriver),否则可能被后续版本覆盖或引发未定义行为
最易被忽略的是:CI4.7.2 的 .env 文件一旦加载,就无法在运行时重新读取。修改后必须重启 Web 服务(PHP-FPM 或 Apache)才能生效,opcache.revalidate_freq 设为 0 也无用——因为 DotEnv 是启动阶段一次性解析,不走 OPcache 缓存路径。











