事件?
CodeIgniter 事件特性提供了一種方法來修改框架的內部運作流程或功能,而無需修改核心文件的能力。CodeIgniter 遵循著一個特定的流程來 運行。但是,在某些情況下,你可能想在執行特定流程時執行某些特定的操作。例如在加載控制器之前或之后立即運行一個特定的腳本。或者在其他的 某些位置觸發你的腳本。
事件已發布/訂閱模式工作,可以在腳本執行過程中的某個時刻觸發事件。其他腳本可以通過向 Events 類來注冊訂閱事件,使它知道在腳本觸發事件 時該執行什么操作。
啟用事件?
事件始終處于啟用狀態,并且全局可用。
定義事件?
大多數的事件都定義在 app/Config/Events.php 文件中。不過你也可以通過 Events 類的 on()
方法定義事件。第一個參數是事件
名稱,第二個參數是當觸發該事件時執行的操作:
use CodeIgniter\Events\Events;
Events::on('pre_system', ['MyClass', 'MyFunction']);
在這個例子中,任何時候觸發 pre_controller 事件,都會創建 MyClass
實例并運行 MyFunction
方法。
第二個參數可以是 PHP 能識別的任何 可調用結構:
// 調用 some_function 方法
Events::on('pre_system', 'some_function');
// 調用實例方法
$user = new User();
Events::on('pre_system', [$user, 'some_method']);
// 調用靜態方法
Events::on('pre_system', 'SomeClass::someMethod');
// 使用閉包形式
Events::on('pre_system', function(...$params)
{
. . .
});
設置執行優先順序?
由于可以將多個方法訂閱到一個事件中,因此需要一種方式來定義這些方法的調用順序。你可以通過傳遞優先級作為 on()
方法的第三個參數來實現。
事件系統將優先執行優先級較低的值,優先級最高的值為 1:
Events::on('post_controller_constructor', 'some_function', 25);
如果出現相同優先級的情況,那么事件系統將按定義的順序執行。
注解
可以理解為事件系統會根據事件名稱分組排序,按第三個參數升序排列,然后依次執行。
Codeigniter 內置了三個常量供您使用,僅供參考。你也可以不使用它,但你會發現他們有助于提高可讀性:
define('EVENT_PRIORITY_LOW', 200);
define('EVENT_PRIORITY_NORMAL', 100);
define('EVENT_PRIORITY_HIGH', 10);
排序后,將按順序執行所有訂閱者。如果任意訂閱者返回了布爾類型 false
,訂閱者將停止執行。
發布自定義的事件?
使用事件系統,你可以輕松創建自己的事件。要使用此功能,只需要調用 Events 類的 trigger()
方法即可:
\CodeIgniter\Events\Events::trigger('some_event');
當然,你也可以為訂閱者傳遞任意數量的參數,訂閱者將會按相同的順序接收參數:
\CodeIgniter\Events\Events::trigger('some_events', $foo, $bar, $baz);
Events::on('some_event', function($foo, $bar, $baz) {
...
});
模擬事件?
在測試期間,你可能不希望事件被真正的觸發,因為每天發送數百封電子郵件記緩慢又適得其反。你可以告訴 Events 類使用 simulate()
方法
模擬運行事件。如果為 true,那么將跳過所有事件,不過其他的內容都會正常運行:
Events::simulate(true);
你也可以傳遞 false 停止模擬:
Events::simulate(false);
事件觸發點?
以下是 Codeigniter 核心代碼中可用的事件觸發點列表:
- pre_system 系統執行過程中最早被調用。此時,只有 基準測試類 和 鉤子類 被加載了, 還沒有執行到路由或其他的流程。
- post_controller_constructor 在你的控制器實例化之后立即執行,控制器的任何方法都還未調用。
- post_system 最終數據發送到瀏覽器之后,系統執行結束時調用。