CodeIgniter 的 Hook(鉤子)機制提供了在不修改核心程式碼前提下擴展框架功能的強大途徑。透過預定義的執行節點(如 pre_system、pre_controller、post_controller 等),開發者可在系統關鍵階段注入自訂邏輯。本文將剖析 Hook.php 核心原始碼,揭示其初始化、註冊、調用全流程。
class CI_Hooks {
var $enabled = FALSE; // 是否啟用
var $hooks = array(); // 所有鉤子定義
var $in_progress = FALSE; // 防止重入標記
function __construct() {
$this->_initialize();
}
function _initialize() {
// 1. 讀取 config.php 中 $config['enable_hooks']
// 2. 載入 config/hooks.php 定義陣列至 $this->hooks
// 3. 設定 $this->enabled = TRUE
}
function _call_hook($which) {
// 依鉤子節點名稱(如 pre_system)調用對應鉤子
// 支援單一鉤子或多個鉤子陣列
}
function _run_hook($data) {
// $data 為 hooks.php 中單一鉤子定義陣列
// 1. 載入檔案:APPPATH . $data['filepath'] . '/' . $data['filename']
// 2. 實例化類別:new $data['class']()
// 3. 呼叫方法:$obj->$data['function']($data['params'])
}
}
application/config/config.php 設定 $config['enable_hooks'] = TRUE;application/config/hooks.php,例:
$hook['pre_controller'] = [
'class' => 'AuthCheck',
'function' => 'verify',
'filename' => 'AuthCheck.php',
'filepath' => 'hooks',
'params' => ['redirect' => 'login']
];
application/hooks/AuthCheck.php 建立類別與方法| 節點 | 觸發時機 | 典型應用 |
|---|---|---|
| pre_system | 系統初始化極早期 | 全域常數定義、效能監控啟動 |
| pre_controller | 控制器實例化前 | 權限驗證、語言偵測、維護模式 |
| post_controller_constructor | 控制器建構子執行後 | 載入通用 Library、模板變數注入 |
| post_controller | 控制器方法執行後 | 頁面快取、資料紀錄 |
| display_override | 覆蓋 _display() 方法 | 自訂輸出壓縮、模板引擎整合 |
同一節點可定義多個 Hook,系統會依陣列順序依序執行。若需控制優先序,調整 hooks.php 中陣列順序即可。
application/hooks/ 目錄,保持結構清晰params 傳遞配置,提高複用性log_message('debug', 'Hook 執行: ' . $which) 便於除錯掌握 Hook 機制,即可在 CodeIgniter 中實現 AOP 風格的橫切關注點分離,讓核心業務邏輯更專注、擴展功能更彈性。