Yii2 EVENT事件的了解


原文地址:http://www.cnblogs.com/Hzhihua/p/7352122.html
參考資料:

最近一直在學習Yii2框架,在這記錄自己對Yii2事件的了解

事件介紹

使用事件,可以在特定的時點,觸發執行預先設定的一段代碼,事件既是代碼解耦的一種方式,也是設計業務流程的一種模式。現代軟件中,事件無處不在,比如,你發了個微博,觸發了一個事件,導致關注你的人,看到了你新發出來的內容。對於事件而言,有這么幾個要素:

  • 這是一個什么事件?一個軟件系統里,有諸多事件,發布新微博是事件,刪除微博也是一種事件。
  • 誰觸發了事件?你發的微博,就是你觸發的事件。
  • 誰負責監聽這個事件?或者誰能知道這個事件發生了?服務器上處理用戶注冊的模塊,肯定不會收到你發出新微博的事件。
  • 事件怎么處理?對於發布新微博的事件,就是通知關注了你的其他用戶。
  • 事件相關數據是什么?對於發布新微博事件,包含的數據至少要有新微博的內容,時間等

代碼實現

對象級別綁定

事例介紹:有一只貓,它一叫老鼠就會跑
為了實現這個事例,我們在 frontend 文件夾中創建 event文件夾
event文件夾 中2個類文件,一個Cat類,一個Mouse

<?php

namespace frontend\event;

/**
 * 貓類
 * Class: \frontend\event\Cat
 * 
 * 為了讓貓具有事件能力
 * 所以要繼承 \yii\base\Component
 * >>> \yii\base\Component 對 \yii\base\Event 的 on 方法進行重寫
 * >>> \yii\base\Event 適合類級綁定
 * >>> \yii\base\Component 適合對象級綁定
 */
class Cat extends \yii\base\Component
{
	/**
	 * 貓發出叫聲
	 */
	public function shout()
	{
		echo '貓:miao miao miao <br />';
        
		// 貓叫了之后 觸發貓的 miao 事件
		$this->trigger('miao');
	}
}

Mouse.php

<?php

namespace frontend\event;

/**
 * 老鼠類
 * Class: \frontend\event\Mouse
 */
class Mouse
{
	public function run()
	{
		echo '老鼠:有貓來了,趕緊跑啊~~<br />';
	}
}

EventController.php

<?php

namespace frontend\controllers;

use frontend\event\Cat;
use frontend\event\Mouse;

/**
* Class: \frontend\controllers\Event
*/
class EventController extends \yii\web\Controller
{
	public function actionTest()
	{
		$cat = new Cat();
		$mouse = new Mouse();

		// 需事先給貓綁定 miao 事件才可以觸發此事件
		// 貓一叫,就觸發老鼠的 run 方法
		$cat->on('miao', [$mouse, 'run']);

		// 貓發出叫聲
		$cat->shout();
	}
}

在瀏覽器輸入http://yourdomain.com/?r=event/test
得到

貓:miao miao miao 
老鼠:有貓來了,趕緊跑啊~~

通過調用貓的 shout 方法,觸發 miao 事件,老鼠就跑了

突然間,有一天,狗加入這件事例,只要貓一叫,狗就會去找貓
so 也是在event文件夾中
加入狗成員 Dog.php

<?php

namespace frontend\event;

/**
 * Class \frontend\event\Dog
 */
class Dog extends \yii\base\Component
{
	/**
	 * 找貓
	 */
	public function findCat()
	{
		echo '狗:wang wang wang, 貓在哪里??';
	}
}

修改 frontend/controllers/EventController.php
添加狗找貓事件

...
// 需事先給貓綁定 miao 事件才可以觸發此事件
// 貓一叫,就觸發老鼠的 run 方法
$cat->on('miao', [$mouse, 'run']);
$cat->on('miao', [$dog, 'findCat']); // 添加狗找貓事件

// 讓貓發出叫聲
$cat->shout();
...

在瀏覽器中刷新http://yourdomain.com/?r=event/test
得到

貓:miao miao miao 
老鼠:有貓來了,趕緊跑啊~~
狗:wang wang wang, 貓在哪里??

突然間,狗覺得很無聊,不想去找貓了,隨便它叫了
那么我們只需將狗找貓事件取消綁定
修改 frontend/controllers/EventController.php

use frontend\event\Cat;
use frontend\event\Mouse;
use frontend\event\Dog;
...
public function actionTest()
{
    $cat = new Cat();
    $mouse = new Mouse();
    $dog = new Dog();

    // 需事先給貓綁定 miao 事件才可以觸發此事件
    // 貓一叫,就觸發老鼠的 run 方法
    $cat->on('miao', [$mouse, 'run']);
    $cat->on('miao', [$dog, 'findCat']);

    // 並非直接刪除 $cat->on('miao', [$dog, 'findCat']);
    // 而是通過 off 解除綁定
    $cat->off('miao', [$dog, 'findCat']);

    // 讓貓發出叫聲
    $cat->shout();
}
...

所以得到的最終結果自然少了狗的聲音

類級別綁定

但是有一個問題,以上事件直針對 $cat 所賦值的對象,
即在 frontend/controllers/EventController.php 中的 actionTest 方法末尾中添加 (new Cat())->shout(); 不會觸發 miao 事件

public function actionTest()
{
    ... 

    // 讓貓發出叫聲
    $cat->shout(); // 會觸發 miao 事件
    (new Cat())->shout(); // 不會觸發 miao 事件
}

原因:都是通過$cat對象進行事件綁定的
那有沒有一種,只要是貓發出的聲音,老鼠就跑呢??
這就需要用到類級別的事件綁定

類級別事件綁定需要用到 \yii\base\Event類
修改 frontend/controllers/EventController.php

use frontend\event\Cat;
use frontend\event\Mouse;
use yii\base\Event;
...
public function actionTest()
{
    $cat = new Cat();
    $mouse = new Mouse();

    // 類級別的事件綁定
    // 只要貓發出聲音,不管是什么貓,都會觸發老鼠的 run 方法
    Event::on(Cat::className() ,'miao', [$mouse, 'run']);

    // 讓貓發出叫聲
    $cat->shout(); // 會觸發 miao 事件
    (new Cat())->shout(); // 會觸發 miao 事件
}

刷新頁面,得到

貓:miao miao miao 
老鼠:有貓來了,趕緊跑啊~~
貓:miao miao miao 
老鼠:有貓來了,趕緊跑啊~~

總結

  • 事件綁定分類對象級別和類級別的綁定
  • 對象級別只針對某一個實例化的對象
  • 類級別對所有實例化的對象都起效

如果以上理解有錯誤,歡迎提出和指正

參考資料:

原文地址:http://www.cnblogs.com/Hzhihua/p/7352122.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM