environment常量必须在index.php开头定义,仅限'development'、'testing'、'production'三值,框架加载前未定义则无效;配置按环境目录回退,cli需额外设置环境变量。

必须在 index.php 最开头定义 ENVIRONMENT,晚于任何 require 或 include 都无效。
ENVIRONMENT 常量必须在 index.php 顶部显式定义
CodeIgniter 不读取 $_SERVER['CI_ENV'] 或 .env 文件自动设环境——它只认 ENVIRONMENT 这个常量,且必须在框架加载前就存在。常见错误是把它塞进中间或末尾,比如放在 require FCPATH . 'vendor/autoload.php'; 后面,此时框架早已初始化完毕,再 define 也白搭。
-
ENVIRONMENT只能是'development'、'testing'或'production'三者之一;传'staging'会被当作'production' - 推荐写法:
define('ENVIRONMENT', 'production');紧接在<?php后,不依赖任何外部变量 - 如果真想用服务器变量(如 Apache 的
SetEnv CI_ENV production),得自己手动提取:define('ENVIRONMENT', $_SERVER['CI_ENV'] ?? 'development');,但注意:Nginx 默认不传$_SERVER['CI_ENV'],需在fastcgi_param中显式设置
配置文件按环境加载的路径和回退规则
CodeIgniter 会优先查找 app/Config/{ENVIRONMENT}/Database.php 这类路径,找不到才回落到 app/Config/Database.php。这不是“合并”,而是单文件级 fallback:某环境缺 Cache.php,就用通用版;但 Database.php 存在,就不会加载通用版的 Cache.php。
- 路径固定为
app/Config/{EnvName}/,不是application/config/{env}/(那是 CI3) - 环境目录下缺失的文件才会回退,已存在的文件完全屏蔽通用版同名文件
-
app/Config/Boot/下的文件不走环境分离逻辑,全部无条件加载;如需按环境设ini_set('display_errors', '1'),得在public/index.php里手动判断ENVIRONMENT再写
CLI 模式下 ENVIRONMENT 生效的前提
运行 php spark 时,ENVIRONMENT 是否生效,取决于你调用的是哪个入口文件。Spark CLI 脚本有自己独立的启动逻辑,不经过 public/index.php,所以直接执行 php spark migrate 不会读取你在 public/index.php 里定义的 ENVIRONMENT。
- 正确做法:确保 CLI 命令走对应环境的入口,例如
php public/index.php spark migrate - 或者在 CLI 执行前手动设环境变量:
CI_ENVIRONMENT=production php spark migrate(CI4 支持该方式) - CI3 的 CLI 完全不识别环境变量,只能靠改
index.php或硬编码入口
自定义配置文件不能放子目录,也不能硬塞进 config.php
新增业务配置(如支付、短信)要新建独立文件,比如 app/Config/Payment.php,返回数组,再用 $this->config->load('Payment') 加载。别把它们写进 app/Config/App.php 或 app/Config/Config.php —— 那些是框架核心开关,不是业务配置收纳盒。
- 自定义配置文件必须在
app/Config/目录下,不能放在app/Config/production/之类子目录里 - 若需按环境差异化,就在
Payment.php里用if (ENVIRONMENT === 'production') { ... }判断,而不是靠目录隔离 - 自动加载要写进
app/Config/Autoload.php的$autoload['config']数组,例如$autoload['config'] = ['Payment', 'Sms'];
最容易被忽略的一点:环境常量影响的是配置加载路径和错误报告级别,但它本身不触发任何自动行为——比如不会自动切换数据库连接、不会自动启用缓存。所有依赖环境的逻辑,最终都要落在具体配置文件里手写判断,或在代码中显式检查 ENVIRONMENT 值。











