The event manager in zend is mainly to achieve:
1. Observer mode
2. Section-oriented design
3. Event-driven architecture
The most basic function of event management is to connect or disconnect listeners from events. Regardless of whether it is connected or disconnected, it is through shared collections; events are triggered and the execution of the interrupt listener is triggered.
<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 is really interested in triggering events, and the most basic way to trigger them is through the trigger() method.
<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>
You can see that the trigger() method actually delegates the behavior of triggering events to the triggerListeners() method
trigger accepts three parameters (event name, target, parameters)
Thetrigger method will create an instance of the event and trigger the event. The trigger calls several truncaters such as setName. These methods can be found in the Event class, and are mainly used to encapsulate the target environment and the parameters passed in.
Regarding the target, what the official website talks about is usually the current object instance. It's actually the element that triggers the event. Can be understood as an identifier of an event
Parameters are the parameters provided to the event, usually the parameters passed to the current function or method.
Example:
<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>
As mentioned before, EventManager is only interested in triggering events. The trigger event here only cares about who is listening to this event, that is, who is the listener?
The listener will connect to the EventManager and specify a named event and a callback function to notify related messages (what are related messages? It is the message you want to be notified). The callback function needs to receive the Event object. The getter of the Event object can get the name, target, and parameters of the event (the previous code example has setName, and vice versa)
Code Example
<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() can be any valid callable PHP function, it can be an anonymous function, or it can use the function name, functor, a string pointing to a static function,,,,
Sometimes, you may want to create a new listener, but don’t want to create a new event. So you want to use the previously created event, then you need to set the previous event to shared (that is, shareable, an event can have multiple listeners). We can achieve this purpose through SharedEventManager.
ZendEventManagerSharedEventManagerInterface describes an object that aggregates several listeners. These listeners are connected to one or more events by using an identifier. SharedEventManager does not trigger these events. On the contrary, the EventManager combines the SharedEventManager and then queries the ShareEventManager to obtain the listener with the same identity, and then triggers it.
<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>
Compared with before, the attach function in the above code adds the first parameter: 'Foo', which means the target of this listener is: Foo, the event is: bar, don't come to me for other targets.
When we originally created the event, we used setIdentifiers(). This function sets the target, which is the logo.
Previously we used ShareEventManager to register a listener, which is shared. Note: Events are not shared, listeners are shared. Now all we need to do is tell event Foo that you can use a listener. We use the following code:
<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');
At the end of the code, we trigger the bar event, which will then trigger the above event. The results will not be described here.
If we use SubFoo to inherit the Foo class, bar() in SubFoo will still trigger our shared event. The reason is that we passed in get_class($this) and __CLASS__ at the same time in Foo's setIndentifiers(). If we call this method in SubFoo, these two parameters return SubFoo and Foo respectively (__CLASS__ is equivalent to get_class() without parameters).