ci 4 不支持钩子机制,已用事件系统替代;需在 app/config/events.php 中注册监听器,通过优先级数值控制同事件内执行顺序,且事件触发时机由框架固定不可跨事件干预。

CI 4 不支持钩子机制,所谓“钩子优先级调整”根本不存在。
这是最常被误解的一点:很多从 CI 3.x 迁移过来的开发者,习惯性去翻 application/config/hooks.php 或尝试设置 $config['enable_hooks'],结果发现完全没反应——不是配置错了,是整个机制已被移除。
为什么 CI 4 没有钩子?
CI 4 用事件系统(Events)替代了旧版钩子。它更灵活、可监听/触发、支持优先级、能跨模块解耦。但关键区别在于:事件不是按“执行顺序硬编码”的钩子点,而是靠监听器注册+权重控制优先级。
怎么在 CI 4 中实现类似 pre_controller 的拦截?
你需要用 Events + 自定义监听器,而不是改钩子配置:
- 在
app/Config/Events.php中注册监听器,例如:Events::on('pre_system', [\App\Listeners\AuthChecker::class, 'check']); - 监听器类必须实现
run()方法或定义静态check()方法 - 优先级通过第三个参数控制:
Events::on('pre_system', [\App\Listeners\AuthChecker::class, 'check'], 10);数值越小越早执行(默认为100) -
pre_system在 CI 实例初始化前触发,此时不能调用service()或model();如需访问数据库或 session,应监听post_controller_constructor类似事件(需自行定义并触发)
常见错误:把 CI 3 的 hooks.php 复制到 CI 4 项目里
这不会报错,但也不会生效。因为:
-
CI 4根本不读取application/config/hooks.php -
$config['enable_hooks']在CI 4的Config/App.php或其他配置文件中不存在 - 即使你手动 require
hooks.php,也没有对应的钩子执行引擎来调度它
如果非要模拟“钩子优先级”,得自己写事件调度逻辑
CI 4 的 Events 本身支持优先级,但只对同一事件下的多个监听器有效。如果你需要跨事件控制顺序(比如让 A 监听器总在 B 监听器之前运行),就得:
- 避免分散监听不同事件(如一个监听
pre_system,另一个监听pre_controller),因为事件触发时机由框架决定,无法人为干预先后 - 把逻辑收敛到同一个事件上,靠优先级数值区分执行次序
- 注意:优先级仅影响同名事件内的监听器顺序,不影响事件本身的生命周期位置











