需启用钩子开关、匹配预设钩子点、合规创建钩子文件、手动触发或扩展Hooks类;首要步骤是将$config['enable_hooks'] = TRUE;并重启服务。

如果您在CodeIgniter 3.x中希望在控制器加载前、输出发送后等关键生命周期节点插入自定义逻辑,但钩子未按预期触发,则可能是由于钩子机制未正确启用或钩子点配置不匹配。以下是实现该机制的多种方法:
一、启用钩子开关并验证基础配置
钩子机制依赖全局开关控制,若未启用,所有钩子定义将被忽略。此步骤是后续所有钩子执行的前提条件,且仅对CI 3.x有效,CI 4完全移除此机制。
1、打开application/config/config.php文件。
2、搜索$config['enable_hooks'],将其值由FALSE改为TRUE。
3、保存文件后,确认该行代码为:$config['enable_hooks'] = TRUE;
4、重启Web服务,避免因缓存导致配置未生效。
二、定义钩子规则并匹配预设钩子点
钩子必须绑定到CI框架内置的挂载点(hook point),拼写错误、大小写不符或使用自定义名称均会导致钩子静默失效。系统在system/core/CodeIgniter.php中硬编码了这些挂载点,例如pre_system位于第129行,post_controller_constructor位于第295行。
1、打开application/config/hooks.php文件。
2、声明$hook数组,并以CI预设钩子点为键名,如'pre_controller'、'post_system'等。
3、每个钩子定义必须包含'function'和'filename'两项,'filepath'需为相对于APPPATH(即application/)的路径,例如写成'hooks'而非'application/hooks/'。
4、示例合法定义:$hook['post_controller_constructor'] = array('function' => 'log_route', 'filename' => 'logger.php', 'filepath' => 'hooks');
三、创建钩子文件并规避实例化时机限制
钩子文件中调用get_instance()存在严格时机约束:pre_system与pre_system钩子中不可用,否则直接报错;仅从pre_controller起,CI核心对象才完成初始化,方可安全访问$this->CI->load、$this->CI->session等组件。
1、在application/hooks/目录下新建文件,如logger.php。
2、文件头部必须添加防护语句:defined('BASEPATH') OR exit('No direct script access allowed');
3、若使用类方式定义钩子,构造函数内可调用get_instance(),但须确保钩子点为pre_controller或之后。
4、函数签名须与params参数数量及顺序一致,例如params => ['admin', 'edit']对应function log_route($role = '', $action = '')。
四、手动触发钩子以应对条件性执行场景
当钩子因路由条件、用户角色等动态因素不应自动触发时,可绕过自动挂载机制,在控制器或模型中显式调用CI_Hooks类的_call_hook()方法,实现精准控制。
1、在需要触发处获取Hooks实例:$hooks =& get_instance()->hooks;
2、确认目标钩子点已存在于$hook数组中,且未处于in_progress状态以防递归。
3、调用内部方法执行:$hooks->_call_hook('post_controller_constructor');
4、注意该操作跳过了CI默认的钩子启用检查,需自行确保$config['enable_hooks']为TRUE且钩子定义语法正确。
五、通过扩展Hooks类实现运行时钩子注册
原生CI_Hooks类将钩子定义静态绑定于config/hooks.php,若需在运行时动态添加钩子(如插件系统),可继承CI_Hooks并重写_initialize()方法,从数据库或JSON配置中加载钩子规则。
1、新建application/core/MY_Hooks.php文件。
2、继承CI_Hooks类,覆盖_construct()方法,在其中调用parent::__construct()后再执行动态加载逻辑。
3、从外部源读取钩子配置,合并入$this->hooks属性,格式须严格遵循原生数组结构。
4、确保system/core/CodeIgniter.php中加载的是MY_Hooks而非CI_Hooks,需修改autoload或手动实例化。

















