《PHP編程:詳解EventDispatcher事件分發組件》要點:
本文介紹了PHP編程:詳解EventDispatcher事件分發組件,希望對您有用。如果有疑問,可以聯系我們。
PHP教程引言
PHP教程考慮這樣一個問題,現在你想給為你的項目提供一個插件系統,插件可以添加一些方法,或者在某些方法執行之前或者之后做些事情,而不干擾其他插件.要實現這個系統,簡單的單繼承不是個好辦法,即使多繼承在PHP中是可能的,他也有與生俱來的缺點(多繼承不太了解,感覺挺操蛋的).
PHP教程Symfony EventDispatcher以一個簡單有效的方式實現了中介者模式,事件分發器就是那個中介,讓系統和插件不會耦合在一起,這讓上面的插件系統成為可能,而且他會讓你的項目可擴展性更好.
PHP教程上面的話,翻譯自Symfony官方文檔片段
PHP教程系統剖析
PHP教程事件存儲
PHP教程
PHP教程上面這張圖是分析Symfony EventDispatcher組件源碼得出來的,可以看到事件在系統中是如何存儲的
PHP教程這里面將事件存儲了兩遍,用來加入優先級priority的概念,存如的時候放入上圖中上面的結構中,取出時候從上圖中下面的結構中拿出來,相同的事件名稱可以有不同的優先級,優先級越高的事件優先觸發,優先級相同的時候,先插入的事件優先觸發.
PHP教程排序事件(上圖中下面的結構)在插入事件的時候不會構建,而是當取出事件的時候會生成排好序的事件,當相同的事件名中插入新的事件或刪除某個事件的時候,會刪除對應的排好序的事件名,后面用到的時候重新構建
PHP教程執行事件的時候,會獲取對應事件名排好序的linster列表,按照順序依次執行.
PHP教程事件執行
PHP教程
PHP教程如上圖所示,當觸發某個時間的時候,該事件名下面如果監聽了多個觸發動作,他們會按照優先級、注冊順序依次觸發,觸發動作一般是一個可執行的“實例”(不管是類還是函數,必須可以通過call_user_func_array調用),可以傳入三個參數,第一個參數(必須)是一個Event實例,第二個是觸發的事件名,第三個是事件分發器實例.第一個參數會控制事件是否在該事件名下的所有觸發動作之間繼續傳遞,比如上面的linstener_2里面將Event.propagationStopped設置為true,執行完linstener_2后,事件就會停止傳播,linstener_2后面的動作不會觸發.
PHP教程除此之外,Event實例中還可以保存其他必要的信息,以便linstener觸發執行的時候,獲取額外的信息.
PHP教程事件訂閱者
PHP教程
PHP教程事件訂閱者(Event subscriber),告訴dispathcer實例,他要訂閱的所有事件,不用一個個通過dispathcer實例去注冊.事件訂閱者是一個PHP類,他可以告訴dispathcer他要訂閱的具體的事件.
PHP教程好處:
PHP教程訂閱者內部關注的事件是一個整體,要么全部關注要么全部不關注
PHP教程實例
PHP教程普通栗子
PHP教程
include "vendor/autoload.php";
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\Event;
class UserEvent extends Event
{
public function name()
{
return "Cartman";
}
public function age()
{
return "24";
}
}
$dispatcher = new EventDispatcher();
$dispatcher->addListener("user.name", function($event, $eventName, $dispatcher){
echo "My name is Cartman\n";
});
$dispatcher->addListener("user.name", function($event, $eventName, $dispatcher){
echo "My name is {$event->name()} from Event instance\n";
}, 10);
$dispatcher->addListener("user.age", function($event, $eventName, $dispatcher){
echo "My age is 24\n";
}, 10);
$dispatcher->addListener("user.age", function($event, $eventName, $dispatcher){
echo "My age is {$event->age()} from Event instance\n";
}, -10);
$dispatcher->dispatch("user.name", new UserEvent());
$dispatcher->dispatch("user.age", new UserEvent());
PHP教程上面的例子輸出
PHP教程
My name is Cartman from Event instance
My name is Cartman
My age is 24
My age is 24 from Event instance
PHP教程事件訂閱者栗子
PHP教程通過Subscriber注冊事件
PHP教程
include "vendor/autoload.php";
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class BookEvent extends Event
{
public $name = self::class;
}
class BookSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return [
"chinese.name" => "chineseNameShow",
"english.name" => [
["englishNameShow", -10],
["englishNameAFter", 10],
],
"math.name" => ["mathNameShow", 100]
];
}
public function chineseNameShow(Event $event)
{
echo "我是漢語書籍\n";
}
public function englishNameShow(Event $event)
{
echo "我是英文書籍\n";
}
public function englishNameAFter(Event $event)
{
echo "我是展示之后的英文書籍[來自于Event實例{$event->name}]\n";
}
public function mathNameShow(Event $event)
{
echo "我是展示的數學書籍\n";
}
}
$dispatcher = new EventDispatcher();
$subscriber = new BookSubscriber();
$dispatcher->addSubscriber($subscriber);
$dispatcher->dispatch("english.name", new BookEvent());
$dispatcher->dispatch("chinese.name");
$dispatcher->removeSubscriber($subscriber);
$dispatcher->dispatch("math.name");
PHP教程輸出為內容:
PHP教程
我是展示之后的英文書籍[來自于Event實例BookEvent]
我是英文書籍
我是漢語書籍
PHP教程以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持維易PHP!
轉載請注明本頁網址:
http://www.snjht.com/jiaocheng/2241.html