zend의 이벤트 관리자는 주로 다음을 구현합니다.
1. 관찰자 모드
2. 측면을 고려한 디자인
3. 이벤트 중심 아키텍처
이벤트 관리의 가장 기본적인 기능은 리스너를 이벤트에 연결하거나 연결 해제하는 것입니다. 연결 여부에 관계없이 공유 컬렉션을 통해 이루어지며 이벤트가 트리거되고 인터럽트 리스너가 실행됩니다.
<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() 메서드에 위임하는 것을 볼 수 있습니다
트리거는 세 가지 매개변수(이벤트 이름, 대상, 매개변수)를 허용합니다.
트리거 메소드는 이벤트 인스턴스를 생성하고 이벤트를 트리거합니다. 트리거는 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 객체의 getter는 이벤트의 이름, 대상 및 매개변수를 가져올 수 있습니다. (이전 코드 예제에는 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 함수, 익명 함수, 함수 이름 functor 또는 정적 함수를 가리키는 문자열을 사용할 수 있습니다. ,
때로는 새 리스너를 만들고 싶지만 새 이벤트를 만들고 싶지 않을 수도 있습니다. 따라서 이전에 생성된 이벤트를 사용하려면 이전 이벤트를 공유로 설정해야 합니다(즉, 공유 가능, 이벤트에 여러 리스너가 있을 수 있음). SharedEventManager를 통해 이 목적을 달성할 수 있습니다.
ZendEventManagerSharedEventManagerInterface는 여러 리스너를 집계하는 개체를 설명합니다. 이러한 리스너는 식별자를 사용하여 하나 이상의 이벤트에 연결됩니다. SharedEventManager는 이러한 이벤트를 트리거하지 않습니다. 반대로 EventManager는 SharedEventManager를 결합한 다음 ShareEventManager에 쿼리하여 동일한 ID를 가진 리스너를 얻은 다음 이를 트리거합니다.
<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>
이전과 비교하면 위 코드의 첨부 함수는 첫 번째 매개변수 'Foo'를 추가합니다. 이는 이 리스너의 대상이 Foo이고 이벤트가 다음과 같습니다. bar, 다른 대상을 위해 나에게 오지 마세요.
처음 이벤트를 생성할 때 setIdentifiers()를 사용했습니다. 이 함수는 로고인 타겟을 설정합니다.
이전에는 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()와 동일합니다).