CI4多环境配置核心是ENVIRONMENT常量与.env文件联动,需通过Web服务器注入CI_ENV环境变量,并确保APP_ENV与CI_ENV一致;数据库等配置应通过env()函数从.env读取,日志和错误显示由APP_DEBUG控制。

CI4 的多环境配置不是靠改文件名或复制 config 目录实现的,核心是 ENVIRONMENT 常量 + .env 文件联动,且必须配合 Web 服务器环境变量注入才安全可靠。
ENVIRONMENT 常量怎么设才不踩坑
CI4 默认在 public/index.php 里定义 ENVIRONMENT,但它的值不能硬写死——比如直接改成 define('ENVIRONMENT', 'production')。这样代码提交后会把生产配置暴露在 Git 里,也容易被本地调试误触发。
正确做法是让 PHP 从服务器环境变量读取:
- Apache:在虚拟主机配置里加
SetEnv CI_ENV production - Nginx:在
server块里加fastcgi_param CI_ENV "production"; - Docker:用
environment:下的CI_ENV: production
然后确保 public/index.php 里这行没被改过:define('ENVIRONMENT', isset($_SERVER['CI_ENV']) ? $_SERVER['CI_ENV'] : 'development');
如果 $_SERVER['CI_ENV'] 没传进来,就 fallback 到 development,开发时不用动任何配置也能跑。
.env 文件怎么配才生效
CI4 启动时会自动加载项目根目录下的 .env 文件,但前提是 APP_ENV 和 CI_ENV 一致——APP_ENV 是 CI4 内部用的环境标识,CI_ENV 是你传给 PHP 的外部变量,两者必须匹配,否则 .env 里写的数据库账号密码、密钥等全不会加载。
所以 .env 文件开头必须写:
APP_ENV = production CI_ENV = production
常见错误:
-
APP_ENV=prod但CI_ENV=production→ 不匹配,.env被忽略 -
.env权限设成 755 或放 Git 里 → 敏感信息泄露风险 - 本地开发用
php spark serve启动时没加--env=development→ 默认走production,报错“database connection failed”
database.php 怎么写才能按环境切换连接
CI4 不再推荐在 app/Config/Database.php 里写一堆 if (ENVIRONMENT === '...') 分支,而是用 .env 变量直接注入配置项。更干净的做法是:删掉所有环境判断逻辑,只保留基础结构,把具体值全交给 .env。
例如 app/Config/Database.php 中保持:
public $default = [
'DSN' => '',
'hostname' => env('DB_HOST', 'localhost'),
'username' => env('DB_USERNAME', ''),
'password' => env('DB_PASSWORD', ''),
'database' => env('DB_DATABASE', ''),
'DBDriver' => env('DB_DRIVER', 'MySQLi'),
'DBPrefix' => '',
// …其余字段保持默认即可
];对应 .env 就写:
# 开发环境 DB_HOST = localhost DB_USERNAME = root DB_PASSWORD = DB_DATABASE = ci4_dev <h1>生产环境</h1><p>DB_HOST = db-prod.example.com DB_USERNAME = app_prod DB_PASSWORD = s3cr3t_p@ss DB_DATABASE = ci4_main
注意:env() 函数第二个参数是 fallback,默认值只用于本地无 .env 时兜底,上线前必须确保 .env 存在且权限为 600。
日志和错误显示怎么随环境自动关开
CI4 的日志级别和错误显示不靠手动开关,而由 APP_DEBUG 控制,它也来自 .env。这个变量直接影响三件事:
-
APP_DEBUG = true→ 错误堆栈显示在页面上,日志写入writable/logs/,且级别为 DEBUG(4) -
APP_DEBUG = false→ 错误只写日志,不显示在页面,日志级别降为 ERROR(1) -
APP_DEBUG必须和APP_ENV同步:开发环境设true,生产环境必须为false
别信“我在 config/App.php 里改了 $logThreshold 就能控制”,那只是覆盖层,底层仍受 APP_DEBUG 主控。真正上线前漏关 APP_DEBUG,等于把 SQL 错误、路径、类名全打在用户浏览器上。
最易被忽略的是:CI4 的 .env 加载发生在框架启动早期,但如果你在中间件或控制器里用 getenv() 读变量,可能读不到——得用 env() 辅助函数,或者确认 DotEnv 已初始化。这点在自定义数据库连接或第三方 SDK 配置时特别关键。


















