CodeIgniter中无真正全局变量,跨请求共享数据须依托常量、配置项、会话或静态属性;$GLOBALS和裸变量在redirect后失效,应使用flashdata传递提示消息。

CodeIgniter 里没有真正意义上的“全局变量”,所有跨请求、跨类、跨视图共享的数据,必须依托明确的生命周期载体——常量、配置项、会话、静态属性或环境变量。硬塞 $GLOBALS 或在控制器里定义裸变量,重定向后就失效,这是最常踩的坑。
用 define() 声明编译期不可变值(只读标识)
适合 APP_NAME、API_VERSION、加密盐值这类部署后不变的标识。必须在框架加载前生效,否则类已实例化再 define 就晚了。
-
application/config/constants.php是唯一安全位置,框架启动时自动引入,早于任何控制器/模型初始化 - 不要写
define('ERR_MSG', '')这种占位符——常量不能改,后续赋值无效,ERR_MSG永远是空字符串 - 避免用常量存业务状态(如用户登录态、表单错误信息),它不支持运行时变更
- 示例:
define('JWT_SECRET_KEY', 'a1b2c3d4');—— 后续任何地方直接用JWT_SECRET_KEY,无须引包或调用
用 $config 数组管理可覆盖的运行时配置
需要按环境切换(开发/测试/生产)、可能被钩子或库动态修改、或需统一访问入口的参数,走配置类比硬编码更可控。
- 新建
application/config/global_settings.php,写$config['default_timezone'] = 'Asia/Shanghai'; - 在
application/config/autoload.php的$autoload['config']中加入'global_settings' - 控制器中用
$this->config->item('default_timezone')获取,支持通过ENVIRONMENT目录下同名文件覆盖 - 注意:配置项是“运行时值”,不是语言级常量;修改它不影响其他请求,也不会污染全局命名空间
用 $_SESSION 或 $this->session 传递一次性的跨请求数据
表单提交失败后重定向到结果页、权限拦截跳转时携带提示消息,必须靠会话——这是解决 redirect() 后变量丢失的正解。
- 在控制器中设置:
$this->session->set_flashdata('alert', '操作成功'); - 在目标视图中读取:
echo $this->session->flashdata('alert');(仅首次读取有效,自动销毁) - 不要用
$this->session->set_userdata()存临时提示,它不会自动清理,容易堆积脏数据 - 若需多步流转(如 A→B→C),用
set_flashdata()链式传递,但超过两跳建议改用数据库或缓存
用静态类属性模拟轻量级全局状态(慎用)
仅适用于 CLI 脚本、日志聚合、调试追踪等非 Web 请求场景。Web 环境下多个并发请求会共享同一静态属性,极易引发状态污染。
- 在
application/helpers/global_helper.php中定义类:class GlobalState { public static $log = []; - 写入:
GlobalState::$log[] = 'DB query took 12ms'; - 读取:
print_r(GlobalState::$log); - 关键限制:PHP-FPM 下每个 worker 进程独立持有该静态属性,无法跨进程同步;Apache mod_php 更危险,整个进程共享
真正麻烦的不是“怎么设”,而是混淆了“生命周期”和“作用域”。一个值该活多久(单次请求?整个部署?)、谁有权改它(框架?环境?代码?)、是否要序列化传输(重定向/跳转)——把这些理清,选哪种方式自然就清楚了。











