CI 4 中 hooks.php 完全不生效是正常现象,因框架已彻底移除钩子机制;应改用中间件、过滤器、事件系统等现代替代方案。

CI 4 中 hooks.php 完全不生效是正常现象
CodeIgniter 4 已彻底移除原生钩子机制,$config['enable_hooks'] 和 application/config/hooks.php 在 CI 4 里没有任何作用。这不是配置错误,也不是路径写错,而是框架层面的删除——CI 4 的执行流程不再预留那些预定义钩子点(如 pre_controller、post_system)。很多开发者把 CI 3 的 hooks.php 直接复制到 CI 4 项目里,发现完全没反应,第一反应是“钩子写错了”,其实只是框架根本不认。
CI 3 钩子迁移到 CI 4 的等效替代方案
CI 4 提供了更现代、更可控的替代机制,不是“钩子失效”,而是“换了一套玩法”:
-
全局前置逻辑:用中间件(Middleware),在
app/Config/Middleware.php中注册,例如BeforeFilter::class可拦截所有请求 -
控制器级初始化:在控制器构造函数中处理,但必须显式调用
parent::__construct(),否则$this->session等服务为null -
路由级拦截:通过路由过滤器(Filters),在
app/Config/Filters.php定义,支持按路由分组启用,比 CI 3 的pre_controller更精准 -
事件系统:CI 4 内置
Events类,可触发/监听自定义事件(如login_success),适合解耦日志、通知等横切逻辑
为什么不能硬套 CI 3 的钩子写法
强行在 CI 4 里模仿 CI 3 钩子会踩多个坑:
-
get_instance()在 CI 4 中已废弃,调用直接报Fatal error: Uncaught Error: Call to undefined function get_instance() - CI 4 的加载顺序是「先容器后控制器」,
pre_system类钩子所依赖的「核心对象尚未创建」这个前提已不存在 - CI 4 使用 PSR-4 自动加载,
filepath和filename这类基于文件路径的配置方式与自动加载机制冲突 - 试图用 Composer 加装旧版
raven/raven或第三方钩子封装包,大概率因 PHP 8+ 兼容性或 autoloader 冲突失败
最常被忽略的迁移细节
开发者从 CI 3 切到 CI 4 后,最容易卡在「以为只是改个配置就能跑通钩子」,结果反复调试 hooks.php 却毫无进展。真正要做的不是修复钩子,而是识别原钩子用途并映射到 CI 4 对应机制:比如原 post_controller_constructor 做权限判断,就该转成 Filters;原 post_system 记日志,就该用 Events 或中间件的 after() 方法。跳过这层语义转换,所有配置和代码都是白忙。


















