CodeIgniter4 事件

2020-08-17 13:37 更新

CodeIgniter 事件特性提供了一種方法來修改框架的內(nèi)部運作流程或功能,而無需修改核心文件的能力。CodeIgniter 遵循著一個特定的流程來 運行。但是,在某些情況下,你可能想在執(zhí)行特定流程時執(zhí)行某些特定的操作。例如在加載控制器之前或之后立即運行一個特定的腳本?;蛘咴谄渌?某些位置觸發(fā)你的腳本。

事件已發(fā)布/訂閱模式工作,可以在腳本執(zhí)行過程中的某個時刻觸發(fā)事件。其他腳本可以通過向 Events 類來注冊訂閱事件,使它知道在腳本觸發(fā)事件 時該執(zhí)行什么操作。

啟用事件

事件始終處于啟用狀態(tài),并且全局可用。

定義事件

大多數(shù)的事件都定義在 app/Config/Events.php 文件中。不過你也可以通過 Events 類的 on() 方法定義事件。第一個參數(shù)是事件 名稱,第二個參數(shù)是當觸發(fā)該事件時執(zhí)行的操作:

use CodeIgniter\Events\Events;


Events::on('pre_system', ['MyClass', 'MyFunction']);

在這個例子中,任何時候觸發(fā) pre_controller 事件,都會創(chuàng)建 MyClass 實例并運行 MyFunction 方法。

第二個參數(shù)可以是 PHP 能識別的任何 可調(diào)用結(jié)構(gòu):

// 調(diào)用 some_function 方法
Events::on('pre_system', 'some_function');


// 調(diào)用實例方法
$user = new User();
Events::on('pre_system', [$user, 'some_method']);


// 調(diào)用靜態(tài)方法
Events::on('pre_system', 'SomeClass::someMethod');


// 使用閉包形式
Events::on('pre_system', function(...$params)
{
        . . .
});

設置執(zhí)行優(yōu)先順序

由于可以將多個方法訂閱到一個事件中,因此需要一種方式來定義這些方法的調(diào)用順序。你可以通過傳遞優(yōu)先級作為 on() 方法的第三個參數(shù)來實現(xiàn)。 事件系統(tǒng)將優(yōu)先執(zhí)行優(yōu)先級較低的值,優(yōu)先級最高的值為 1:

Events::on('post_controller_constructor', 'some_function', 25);

如果出現(xiàn)相同優(yōu)先級的情況,那么事件系統(tǒng)將按定義的順序執(zhí)行。

注解

可以理解為事件系統(tǒng)會根據(jù)事件名稱分組排序,按第三個參數(shù)升序排列,然后依次執(zhí)行。

Codeigniter 內(nèi)置了三個常量供您使用,僅供參考。你也可以不使用它,但你會發(fā)現(xiàn)他們有助于提高可讀性:

define('EVENT_PRIORITY_LOW', 200);
define('EVENT_PRIORITY_NORMAL', 100);
define('EVENT_PRIORITY_HIGH', 10);

排序后,將按順序執(zhí)行所有訂閱者。如果任意訂閱者返回了布爾類型 false,訂閱者將停止執(zhí)行。

發(fā)布自定義的事件

使用事件系統(tǒng),你可以輕松創(chuàng)建自己的事件。要使用此功能,只需要調(diào)用 Events 類的 trigger() 方法即可:

\CodeIgniter\Events\Events::trigger('some_event');

當然,你也可以為訂閱者傳遞任意數(shù)量的參數(shù),訂閱者將會按相同的順序接收參數(shù):

\CodeIgniter\Events\Events::trigger('some_events', $foo, $bar, $baz);


Events::on('some_event', function($foo, $bar, $baz) {
        ...
});

模擬事件

在測試期間,你可能不希望事件被真正的觸發(fā),因為每天發(fā)送數(shù)百封電子郵件記緩慢又適得其反。你可以告訴 Events 類使用 simulate() 方法 模擬運行事件。如果為 true,那么將跳過所有事件,不過其他的內(nèi)容都會正常運行:

Events::simulate(true);

你也可以傳遞 false 停止模擬:

Events::simulate(false);

事件觸發(fā)點

以下是 Codeigniter 核心代碼中可用的事件觸發(fā)點列表:

  • pre_system 系統(tǒng)執(zhí)行過程中最早被調(diào)用。此時,只有 基準測試類 和 鉤子類 被加載了, 還沒有執(zhí)行到路由或其他的流程。
  • post_controller_constructor 在你的控制器實例化之后立即執(zhí)行,控制器的任何方法都還未調(diào)用。
  • post_system 最終數(shù)據(jù)發(fā)送到瀏覽器之后,系統(tǒng)執(zhí)行結(jié)束時調(diào)用。
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號