CI4升级后parent::__construct()必须调用,否则服务注入失效、过滤器不触发、核心对象为null;需检查构造函数首行、参数顺序、配置读取时机及中间件注册方式。

parent::__construct() 必须调用,否则服务注入全失效——这是 CI4 升级后配置“突然不生效”的最常见根因。
CI4 升级后 parent::__construct() 被忽略导致服务为空
升级到 CodeIgniter 4.5+ 后,框架对构造函数执行流程做了更严格的校验。若控制器重写了 __construct() 却没显式调用 parent::__construct(),会导致:
– 请求过滤器(如 before/after)完全不触发
– $this->request、$this->response 等核心对象为 null
– 所有通过 DI 注入的服务(Session、Cache、Database)均为未初始化状态
实操建议:
• 检查所有自定义控制器,确认每处 __construct() 开头第一行是 parent::__construct();
• 若使用 PHP 8.1+,注意类型声明顺序:父类调用必须在任何属性赋值或依赖使用之前
• 不要依赖 IDE 自动生成的构造函数模板——它常漏掉这行
服务注入参数顺序与版本兼容性差异
CI4.4 之前允许构造函数参数顺序松散,但 4.5+ 强制按容器注册顺序解析。若你手动注册了自定义服务(如 MyLogger),而控制器中把它放在 Session 之后,升级后可能因解析错位导致注入失败。
实操建议:
• 查看 app/Config/Services.php 中服务注册顺序,保持控制器参数顺序与之严格一致
• 避免混合注入:不要在一个构造函数里既写类型提示又写 $this->session = service('session') 这种手动获取方式
• 对第三方扩展服务,优先用 service('xxx') 显式获取,而非构造注入,降低耦合风险
配置文件加载时机变化引发的环境误判
CI4.5 调整了 Config 类实例化时机,app/Config/App.php 等配置类在 parent::__construct() 执行前就已加载。若你在构造函数里提前读取 config('App')->baseURL,而该值依赖环境变量(如 CI_ENVIRONMENT=production),升级后可能读到默认值而非实际环境配置。
实操建议:
• 把配置读取逻辑从构造函数移到具体方法(如 index())中
• 如确需在构造阶段使用配置,改用 getenv('CI_ENVIRONMENT') === 'production' 直接判断,绕过 Config 实例
• 检查 .env 文件是否被 gitignore 忽略——本地测试时容易漏传,导致配置始终走默认分支
中间件注册方式变更导致过滤器失效
CI4.4 支持在控制器内用 $this->filters() 声明中间件,但 4.5+ 已废弃该写法,统一要求在路由定义中绑定。升级后若仍沿用旧方式,中间件完全不执行,权限、日志等逻辑静默失效。
实操建议:
• 将原控制器内的 $this->filters()->add('auth'); 全部移至 app/Config/Routes.php
• 示例迁移:$routes->add('admin/users', 'Admin::users', ['filter' => 'auth']);
• 注意:路由组的 filter 会继承,但控制器级 filter 不再支持,别指望它还能 fallback
DEBUG 级别下有没有 Service not found 或 Filter not applied 类提示。


















