iT邦幫忙

0

想在PHP 實現類似 C#的 Event 功能

  • 分享至 

  • xImage

如提:
小魯想在PHP上實現類似 C#的 Event 功能來做上下層物件的溝通橋樑 初步構想是 想說C# Event 基底雖然是delegate 但是使用的時候都是用包裝的class Action 那就用class來實現看看吧~ 所以出現了下面的Code...

<?php
class EventObject
    {
        private $events =[];

        public function Add( $eventName ,callable $event)
        {   
            if(array_key_exists($eventName ,$this->events))
                throw new Exception("Duplicate EventName !!");


            if(!is_string($eventName))
                throw new Exception("EventName Must be String!!");

            $this->events[$eventName] =$event;
        }

        public function Remove($eventName)
        {
            if(!array_key_exists($eventName,$this->events))
                return;

            unset($this->events[$eventName]);
        }

        public function Send( $parameter = null)
        {
            if(count( $this->events)==0)
                return;
      
            if(isset($parameter)){
                foreach($this->events as $event){
                    call_user_func($event ,$parameter);
                }
                return;
            }
            
            foreach($this->events as $event){
                call_user_func($event);
            }
        }

        public function Clear()
        {
            $this->events =[];
        }

    }
?>

然後使用的方法...
發事件的物件~

<?php
class Mod
{
protected $onGetExceptonEvent;
public function __construct()
{
    $this->onGetExceptonEvent = new EventObject();
}
public function ListenGetExceptonEvent( $eventname ,callable $call)
{
    $this->onGetExceptonEvent->Add($eventname ,$call);
}

protected function SendGetExceptonEvent($array)
{
    $this->onGetExceptonEvent->Send($array);
}
}
?>

上層物件~

<?php
class Controller
{
private $mod =null;
public function __construct()
{
$this->mod = new mod();
$this->mod->ListenGetExceptonEvent( "OnGetExceptonHandler" ,
    function($array){$this->OnGetExceptonHandler($array);}
);
}

private function OnGetExceptonHandler($array){
    //TODO 
}
}
?>

雖然上面得Code已經可以正常運作了 但是使用起來總覺得不向C#的Event方便

像是 eventobject是物件 所以要用private藏起來 要給別人聽 要另外寫的函式來給別人聽

像是 監聽時要給函式 要用匿名函式包起來 才塞得進去 (這個我試好久)

像是 在發送事件的時候沒辦法知道要塞幾個參數進去可能會誤用什麼的...

小魯的PHP語法還在學習中 不知道大神們有沒有"方法"或是"建議"幫小魯改善這個功能讓他再方便點
感恩

看更多先前的討論...收起先前的討論...
fillano iT邦超人 1 級 ‧ 2018-09-11 11:12:42 檢舉
請google一下「Observer Pattern(觀察者模式)」,用不同的程式語言都可以實做的。
@fillano 大 感謝你的答覆
不過 EventObject 這個Class 就是依照觀察者模式做出來的 add (註冊) Remove(反註冊) Send(更新) 做成物件的方式是想說 可以方便使用 有需要就宣告一個甚至多個event 來推播 不同的事件.... 只是目前使用上要輸入的Cdoe 有點繁雜 (在把Method 塞進Array 裡這件事) 想問問看有沒有比較簡潔的寫法
fillano iT邦超人 1 級 ‧ 2018-09-11 15:54:42 檢舉
哈哈,沒仔細看救回了,果然就是會這樣...

http://tw2.php.net/manual/en/language.types.callable.php

Callable有幾種構成方式,匿名函數、函數名稱、物件及方法名稱構成的陣列、類別名稱及靜態方法名稱構成的陣列等等。

另外,通常EventObject不會這樣設計,因為通常系統中可能會有多處註冊同一事件,事件觸發時,會逐一呼叫他們註冊的Callable。然後移除時...移除的是某事件中註冊的Callable。

要驗證傳入的Callable,可以用is_callable()函數,參考:
http://tw2.php.net/manual/en/function.is-callable.php
fillano iT邦超人 1 級 ‧ 2018-09-11 16:36:09 檢舉
寫了簡單的測試:
https://gist.github.com/fillano/d7c5a2cef9d5e824db1171ab6d13242b
weiclin iT邦高手 4 級 ‧ 2018-09-11 17:12:30 檢舉
要不要先參考一下別人怎麼做的?
https://github.com/igorw/evenement
@fillano @weiclin 感謝兩位大大提供的範例
小魯需要點時間來消化一下看怎麼修改這個class
另外在問一下 如果 callable 要塞的函式是 private 是不是真的就只能包在 匿名函式裡面了呢?
weiclin iT邦高手 4 級 ‧ 2018-09-11 19:09:49 檢舉
是啊, 不然還能叫 private 嗎
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友回答

立即登入回答