首頁 > php教程 > php手册 > zendframework 事件管理(一)

zendframework 事件管理(一)

WBOY
發布: 2016-08-04 08:53:14
原創
1197 人瀏覽過

zend裡的事件管理器主要是為了實現:

1、觀察者模式

2、面向切面設計

3、事件驅動架構

事件管理最基本的功能是將監聽器與事件連接或斷開。不論時連接還是斷開都是透過shared collections; 觸發事件和中斷監聽器的執行。

<span style="color: #0000ff;">use</span><span style="color: #000000;"> Zend\EventManager\EventManagerInterface;
</span><span style="color: #0000ff;">use</span><span style="color: #000000;"> Zend\EventManager\EventManager;
</span><span style="color: #0000ff;">use</span><span style="color: #000000;"> Zend\EventManager\EventManagerAwareInterface;

</span><span style="color: #0000ff;">class</span> Foo <span style="color: #0000ff;">implements</span><span style="color: #000000;"> EventManagerAwareInterface
{
    </span><span style="color: #0000ff;">protected</span> <span style="color: #800080;">$events</span><span style="color: #000000;">;<br>//将EventManager实例注入到Foo类中
    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> setEventManager(EventManagerInterface <span style="color: #800080;">$events</span><span style="color: #000000;">)
    {
        </span><span style="color: #800080;">$events</span>-><span style="color: #000000;">setIdentifiers([
            </span><span style="color: #ff00ff;">__CLASS__</span>,<span style="color: #000000;">
            get_called_class()</span>,<span style="color: #000000;">
            ]);
    
        </span><span style="color: #800080;">$this</span>->events=<span style="color: #800080;">$events</span><span style="color: #000000;">;
        </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">$this</span><span style="color: #000000;">;
    }<br>//如果EventManager实例不存在,则新建一个实例。
    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> getEventManager()
    {
        </span><span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">null</span> === <span style="color: #800080;">$this</span>-><span style="color: #000000;">events) {
                </span><span style="color: #800080;">$this</span>->setEventManager(<span style="color: #0000ff;">new</span><span style="color: #000000;"> EventManager());
        }
        </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">$this</span>-><span style="color: #000000;">events;
    }
}</span>
登入後複製

EventManager真正感興趣的時觸發事件,最基本的觸發方式時會透過trigger()方法。

<span style="color: #008000;">/*</span><span style="color: #008000;">file:vendor\zendframework\zend-eventmanager\EventManager.php
*trigger方法的具体内容
</span><span style="color: #008000;">*/</span>

<span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> trigger(<span style="color: #800080;">$eventName</span>,  <span style="color: #800080;">$target</span> = <span style="color: #0000ff;">null</span>,  <span style="color: #800080;">$argv</span> =<span style="color: #000000;"> [])
{
    </span><span style="color: #800080;">$event</span> = <span style="color: #0000ff;">clone</span> <span style="color: #800080;">$this</span>-><span style="color: #000000;">eventPrototype;
    </span><span style="color: #800080;">$event</span>->setName(<span style="color: #800080;">$eventName</span><span style="color: #000000;">);
    </span><span style="color: #800080;">$event</span>->setTarget(<span style="color: #800080;">$target</span><span style="color: #000000;">);
    </span><span style="color: #800080;">$event</span>->setParams(<span style="color: #800080;">$argv</span><span style="color: #000000;">);
    
    </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">$this</span>->triggerListeners(<span style="color: #800080;">$event</span><span style="color: #000000;">);
}</span>
登入後複製

可以看到trigger()方法實際上將觸發事件這一行為委託給了triggerListeners()方法

trigger接受三個參數(事件名,目標,參數)

trigger方法將會建立事件的實例並觸發事件。 trigger呼叫了setName等幾個截斷器。這幾個方法可以在Event類別裡面找到,主要用來封裝目標環境和被傳遞進來的參數。

關於目標,官網上講的是通常為當前物件實例。實際上就是觸發事件的元素。可以理解為事件的標識

參數則是提供給事件的參數,通常是傳遞給目前函數或方法的參數。

舉例:

<span style="color: #0000ff;">class</span><span style="color: #000000;"> Foo
{<br>//....assume events definition from above
    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> bar(<span style="color: #800080;">$baz</span>, <span style="color: #800080;">$bat</span> = <span style="color: #0000ff;">null</span><span style="color: #000000;">) 
    {
        </span><span style="color: #800080;">$params</span> = <span style="color: #008080;">compact</span>('baz', 'bat'<span style="color: #000000;">);
        </span><span style="color: #800080;">$this</span>->getEventManager()->trigger(<span style="color: #ff00ff;">__FUNCTION__</span>, <span style="color: #800080;">$this</span>, <span style="color: #800080;">$params</span><span style="color: #000000;">);
    }
}</span>
登入後複製

之前講過,EventManager只對觸發事件感興趣。這裡觸發事件則只關心誰在監聽本事件,也就是監聽器是誰?

監聽器會連接到EventManager,指定一個命名的事件和一個回呼函數用來通知相關訊息(啥叫相關訊息呢?就是你想通知的訊息)。回呼函數需要接收Event對象,Event對象的獲取器可以取得事件的名字,目標,和參數(之前程式碼實例中有setName,反之則是getName)

程式碼實例

<span style="color: #0000ff;">use</span> Zend\<span style="color: #008080;">Log</span>\Factory <span style="color: #0000ff;">as</span><span style="color: #000000;"> LogFactory;
</span><span style="color: #800080;">$log</span> = LogFactory(<span style="color: #800080;">$someConfig</span><span style="color: #000000;">);
</span><span style="color: #800080;">$foo</span> = <span style="color: #0000ff;">new</span><span style="color: #000000;"> Foo();
</span><span style="color: #800080;">$foo</span>->getEventManager()->attach('bar', <span style="color: #0000ff;">function</span>(<span style="color: #800080;">$e</span>) <span style="color: #0000ff;">use</span>(<span style="color: #800080;">$log</span><span style="color: #000000;">) {
    </span><span style="color: #800080;">$event</span> = <span style="color: #800080;">$e</span>-><span style="color: #000000;">getName();
    </span><span style="color: #800080;">$target</span> = <span style="color: #008080;">get_class</span>(<span style="color: #800080;">$e</span>-><span style="color: #000000;">getTarget());
    </span><span style="color: #800080;">$params</span> = json_encode(<span style="color: #800080;">$e</span>-><span style="color: #000000;">getParams());

    </span><span style="color: #800080;">$log</span>->info(<span style="color: #008080;">sprintf</span><span style="color: #000000;">(
        </span>'<span style="color: #000000;">%s called on %s, using params %s,
        $event,
        $target,
        $params
    ));
});

//以下bar方法调用时,事件会被触发,监听器便会被执行
$foo->bar(</span>'baz', 'bat'<span style="color: #000000;">)
//Result:
//bar called on Foo, using params {"baz": "baz", "bat":"bat"}"</span>
登入後複製

attach()的第二個參數可以是任何有效的可呼叫的PHP函數,可以是匿名函數,也可以使用函數名稱、仿函數、指向靜態函數的字串、、、、

  有時候呢,你可能想創建一個新的監聽器,但又不想創建新的事件。於是你想要使用之前建立的事件,這時候你就要將之前的事件設定為shared(就是可分享的,一個事件可以有多個監聽器)。我們可以透過SharedEventManager來達成這項目的。

  ZendEventManagerSharedEventManagerInterface描述了一個聚合數個監聽器的物件。這些監聽器透過使用標識連接一個或多個事件。 SharedEventManager不會觸發這些事件。相反,是由EventManager組合SharedEventManager之後查詢ShareEventManager取得標識一致的監聽器,然後觸發。 

<span style="color: #0000ff;">use</span><span style="color: #000000;"> Zend\EventManager\SharedEventManager;

</span><span style="color: #800080;">$sharedEvents</span> = <span style="color: #0000ff;">new</span><span style="color: #000000;"> SharedEventManager();
</span><span style="color: #800080;">$sharedEvents</span>->attach('Foo', 'bar', <span style="color: #0000ff;">function</span>(<span style="color: #800080;">$e</span><span style="color: #000000;">){
    </span><span style="color: #800080;">$event</span> = <span style="color: #800080;">$e</span>-><span style="color: #000000;">getName();
    </span><span style="color: #800080;">$target</span> =<span style="color: #008080;">get_class</span>(<span style="color: #800080;">$e</span>-><span style="color: #000000;">getTarget());
    </span><span style="color: #800080;">$params</span> = <span style="color: #800080;">$e</span>-><span style="color: #000000;">getParams();
    </span><span style="color: #008080;">printf</span><span style="color: #000000;">(
        </span>'Handled event "%s" on target "%s", with parameters %s',
        <span style="color: #800080;">$event</span>,
        <span style="color: #800080;">$target</span>,<span style="color: #000000;">
        json_encode(</span><span style="color: #800080;">$params</span><span style="color: #000000;">)
    );
});</span>
登入後複製

上面程式碼的attach函數與之前相比增加了第一個參數:‘Foo',意思本監聽器的目標是:Foo,事件是:bar,其他的目標不要來找我啦。

  而我們當初創建事件的時候,使用了setIdentifiers()。這個函數便設定了target,也就是標識。

  之前我們使用了ShareEventManager註冊了一個監聽器,該監聽器是共用的。注意:事件不共享,監聽器共享。現在我們要做的就是告訴事件Foo:你可以使用某個監聽喇叭啦。我們使用以下程式碼:

<span style="color: #800080;">$foo</span> = <span style="color: #0000ff;">new</span><span style="color: #000000;"> Foo();
</span><span style="color: #800080;">$foo</span>->getEventManager()->setSharedManager(<span style="color: #800080;">$sharedEvents</span><span style="color: #000000;">);
</span><span style="color: #800080;">$foo</span>->bar('bar', 'bat');
登入後複製

程式碼的最後我們觸發了bar事件,隨之會觸發上面的事件,結果就不累述了。

  如果我們使用SubFoo繼承Foo類,SubFoo裡的bar()仍然會觸發我們的共享事件。原因是們在Foo的setIndentifiers()裡同時傳入了get_class($this),__CLASS__。如果我們在SubFoo裡面呼叫該方法,這兩個參數分別回傳SubFoo和Foo(__CLASS__相當於get_class()不帶參數)。

 

 

  

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
最新問題
熱門推薦
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板