CI 3.x 的 hooks 仍可用但限制极多:仅支持8个固定钩子点、需静态注册、无法传参、默认关闭;替代方案应使用基类、自定义加载器或重写 Output 方法。

CodeIgniter 的 hooks 机制在现代 CI 开发中基本已失效,不建议新项目启用,但老项目维护时仍需理解其触发逻辑和替代路径。
CI 3.x 的 hooks 还能用吗?
能用,但限制极多:仅支持 pre_system、post_controller_constructor 等 8 个固定位置;所有钩子必须在 application/config/hooks.php 中静态注册;无法传参、不能动态启用/禁用;且默认关闭($config['enable_hooks'] = FALSE)。
常见错误现象:Hook does not exist 或钩子完全不执行——多数是拼写错 hook_point 名,或文件未放在 application/hooks/ 下,或没设 include_once 路径。
- 确保
$config['enable_hooks'] = TRUE在config.php中提前加载 - 钩子函数不能是类方法,只能是全局函数或
static方法 -
post_controller后无法修改输出,因Output类已发送响应头
哪些场景曾依赖 hooks?现在怎么替代?
典型老用法:统一日志记录(post_controller)、权限拦截(pre_controller)、模板注入(display_override)。这些现在都该交给更可控的机制:
- 权限控制 → 改用基类
MY_Controller构造函数中调用$this->auth->check() - 请求前处理 → 在
core/My_Loader.php的initialize()中注入逻辑(比pre_system更早且可访问 CI 实例) - 响应后处理 → 重写
Output::_display()或使用output_compression配置 + 自定义回调
注意:display_override 钩子虽保留,但会绕过整个 CI 输出流程,极易导致缓存、gzip、HTTP 头设置失效。
hooks.php 配置里最容易写错的参数
三个关键键名必须全小写、无下划线:enabled、hook_point、filename。漏掉任一都会静默失败。
$hook['pre_controller'] = array(
'class' => 'Auth_hook',
'function' => 'check_login',
'filename' => 'Auth_hook.php',
'filepath' => 'hooks'
);
常见坑:
-
filepath是相对于APPPATH的路径,不是完整路径,写成application/hooks就错 -
class和function同时存在时,CI 会尝试调用$class::$function();若只写function,则调用全局函数 - 多个同名
hook_point会按数组顺序执行,但无依赖管理 —— 顺序错可能导致$this->db尚未初始化就访问
钩子真正的复杂点不在写法,而在于它把逻辑耦合进框架生命周期的黑盒阶段,调试时看不到调用栈,出错难定位。CI 4 已彻底移除 hooks,转向中间件和事件系统,这个信号很明确:别再往老路上加补丁了。









