zend里的事件管理器主要是为了实现:

1、观察者模式

2、面向切面设计

3、事件驱动构架

事件管理最基本的功能是将监听器与事件连接或断开。不论时连接还是断开都是通过shared collections; 触发事件和中断监听器的执行。

use Zend\EventManager\EventManagerInterface;
use Zend\EventManager\EventManager;
use Zend\EventManager\EventManagerAwareInterface; class Foo implements EventManagerAwareInterface
{
protected $events;
//将EventManager实例注入到Foo类中
public function setEventManager(EventManagerInterface $events)
{
$events->setIdentifiers([
__CLASS__,
get_called_class(),
]); $this->events=$events;
return $this;
}
//如果EventManager实例不存在,则新建一个实例。
public function getEventManager()
{
if (null === $this->events) {
$this->setEventManager(new EventManager());
}
return $this->events;
}
}

EventManager真正感兴趣的时触发事件,最基本的触发方式时通过trigger()方法。

/*file:vendor\zendframework\zend-eventmanager\EventManager.php
*trigger方法的具体内容
*/ public function trigger($eventName, $target = null, $argv = [])
{
$event = clone $this->eventPrototype;
$event->setName($eventName);
$event->setTarget($target);
$event->setParams($argv); return $this->triggerListeners($event);
}

可以看到trigger()方法实际上将触发事件这一行为委托给了triggerListeners()方法

trigger接受三个参数(事件名,目标,参数)

trigger方法将会创建事件的实例并触发事件。trigger调用了setName等几个截断器。这几个方法可以在Event类里面找到,主要用来封装目标环境和被传递进来的参数。

关于目标,官网上讲的是通常为当前对象实例。实际上就是触发事件的元素。可以理解为事件的标识

参数则是提供给事件的参数,通常是传递给当前函数或方法的参数。

举例:

class Foo
{
//....assume events definition from above
public function bar($baz, $bat = null)
{
$params = compact('baz', 'bat');
$this->getEventManager()->trigger(__FUNCTION__, $this, $params);
}
}

之前讲过,EventManager只对触发事件感兴趣。这里触发事件则只关心谁在监听本事件,也就是监听器是谁?

监听器会连接到EventManager,指定一个命名的事件和一个回调函数用来通知相关消息(啥叫相关消息呢?就是你想通知的消息)。回调函数需要接收Event对象,Event对象的获取器可以获取事件的名字,目标,和参数(之前代码实例中有setName,反之则是getName)

代码实例

use Zend\Log\Factory as LogFactory;
$log = LogFactory($someConfig);
$foo = new Foo();
$foo->getEventManager()->attach('bar', function($e) use($log) {
$event = $e->getName();
$target = get_class($e->getTarget());
$params = json_encode($e->getParams()); $log->info(sprintf(
'%s called on %s, using params %s,
$event,
$target,
$params
));
}); //以下bar方法调用时,事件会被触发,监听器便会被执行
$foo->bar('baz', 'bat')
//Result:
//bar called on Foo, using params {"baz": "baz", "bat":"bat"}"

attach()的第二个参数可以是任何有效的可调用的PHP函数,可以是匿名函数,也可以使用函数名、仿函数、指向静态函数的字符串、、、、

  有时候呢,你可能想创建一个新的监听器,但又不想创建新的事件。于是你想使用之前创建的事件,这时候你就要将之前的事件设置为shared(就是可分享的,一个事件可以有多个监听器)。我们可以通过SharedEventManager来达成这一目的。

  Zend\EventManager\SharedEventManagerInterface描述了一个聚合数个监听器的对象。这些监听器通过使用标识连接一个或多个事件。SharedEventManager不会触发这些事件。相反,是由EventManager组合SharedEventManager之后查询ShareEventManager获得标识一致的监听器,然后触发。 

use Zend\EventManager\SharedEventManager;

$sharedEvents = new SharedEventManager();
$sharedEvents->attach('Foo', 'bar', function($e){
$event = $e->getName();
$target =get_class($e->getTarget());
$params = $e->getParams();
printf(
'Handled event "%s" on target "%s", with parameters %s',
$event,
$target,
json_encode($params)
);
});

上面代码的attach函数与之前相比添加了第一个参数:‘Foo',意思本监听器的目标是:Foo,事件是:bar,其他的目标不要来找我啦。

  而我们当初创建事件的时候,使用了setIdentifiers()。这个函数便设置了target,也就是标识。

  之前我们使用了ShareEventManager注册了一个监听器,该监听器是共享的。注意:事件不共享,监听器共享。现在我们需要做的就是告诉事件Foo:你可以使用某个监听器啦。我们使用如下代码:

$foo = new Foo();
$foo->getEventManager()->setSharedManager($sharedEvents);
$foo->bar('bar', 'bat');

代码的最后我们触发了bar事件,随之会触发上面的事件,结果就不累述了。

  如果我们使用SubFoo继承Foo类,SubFoo里的bar()仍然会触发我们的共享事件。原因是们在Foo的setIndentifiers()里同时传入了get_class($this),__CLASS__。如果我们在SubFoo里面调用该方法,这两个参数分别返回SubFoo和Foo(__CLASS__相当于get_class()不带参数)。

  

zendframework 事件管理(一)的更多相关文章

  1. zendframework 事件管理(二)

    首先需要明确的几个问题: Q1.什么是事件? A:事件就是一个有名字的行为.当这个行为发生的时候,称这个事件被触发. Q2.监听器又是什么? A:监听器决定了事件的逻辑表达,由事件触发.监听器和事件往 ...

  2. JavaScript 事件管理

    在设计JavaScript xxsdk的时候考虑到能让调用者参与到工作流程中来,开始用了回调函数.如下: this.foo = function(args,callbackFn) { //do som ...

  3. jquery技巧之让任何组件都支持类似DOM的事件管理

    本文介绍一个jquery的小技巧,能让任意组件对象都能支持类似DOM的事件管理,也就是说除了派发事件,添加或删除事件监听器,还能支持事件冒泡,阻止事件默认行为等等.在jquery的帮助下,使用这个方法 ...

  4. Redis事件管理(二)

    Redis的定时器是自己实现的,不是很复杂.说说具体的实现吧. 定时器的存储维护采用的是普通的单向链表结构,具体节点定义为: /*时间定时器结构体*/ typedef struct aeTimeEve ...

  5. Redis事件管理(一)

    Redis统一的时间管理器,同时管理文件事件和定时器, 这个管理器的定义: #if defined(__APPLE__) #define HAVE_TASKINFO 1 #endif /* Test ...

  6. Redis事件管理(三)

    Redis的事件管理和定时器的管理都是自己来实现的,Redis的事件管理分为两部分,一部分是封装了系统的异步事件API,还有一部分是在这基础上封装了一个通用的事件管理器,根据具体的系统来决定具体使用哪 ...

  7. Backbone事件管理——Backbone.Events模块API结构

    模块Backbone.Events的事件管理是通过Backbone提供的Events API来实现的,该API在1.0版本之前仅仅提供了几个基本的方法,如on.off.trigger.once分别执行 ...

  8. phalcon: plugin 结合Manager事件管理、dispatcher调度控制器 监听sql日志记录或其他拦截出来

    可能用到的类 phalcon\mvc\use\plugin Phalcon\Mvc\Dispatcher as MvcDispatcher Phalcon\Events\Manager as Even ...

  9. phalcon:model 事件与事件管理器

    事件与事件管理器(Events and Events Manager)¶ Models allow you to implement events that will be thrown when p ...

随机推荐

  1. Mindjet MindManager 2016/2017 折腾记录

    https://community.mindjet.com/mindjet/topics/ensure-2017-64-bit-version-installation Mindmanager sho ...

  2. android 开源库集合的链接列表

    1.  内容挺多的 https://github.com/Trinea/android-open-project

  3. Java作业 输入圆的半径计算输出圆的周长和面积

    package text1; import java.util.Scanner; public class text11 { public static void main(String[] args ...

  4. 1369 xth 砍树

    1369 xth 砍树  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond 题解       题目描述 Description 在一个凉爽的夏夜,xth 和 ...

  5. 【转】IT管理人才必备的十大能力

    作为IT技术人员,相信没有一个人愿意永远在底层编写程序或做简单的系统维护.经过一段时间的技术和经验的积累,很多人都向往更高层的职位,但如何能成为一个专业的IT管理人才,并不是每一个人都清晰.明了. & ...

  6. GAN

    GAN(Generative Adversarial Nets),产生式对抗网络 存在问题: 1.无法表示数据分布 2.速度 3.resolution太小,大了无语义信息 4.无reference 5 ...

  7. Android-短信验证

    一.mob.com移动开发者服务平台(ShareSDK)的认识 该平台主要是致力于解决移动开发者的实际需求,同时也致力于一些第三方平台的框架支持,那么这样我们可以更方便的将一些功能集成到我们的App中 ...

  8. Part 82 to 85 Talking about Generic queue, stack collection class

    Part 82   Generic queue collection class Part 83   Generic stack collection class Part 84   Real tim ...

  9. iOS-单例模式-使用技巧

    SingleModel-单例模式 单例可以保证在程序运行过程,一个类只有一个实例(一个对象) 一般将单例设置成宏,这样在使用的时候可以很方便. 我们可以按照下面的步骤实现单例 1.自定义一个.h文件, ...

  10. webSphere提示SSL证书过期,解决方法

    1.点击Security ------SSL certificate and key management2.点击Related Items下的key stores and certificates3 ...