序
考虑这个问题。现在您想为您的项目提供一个插件系统。插件可以在执行一些方法之前或之后添加一些方法或做一些事情,而不会干扰其他插件。要实现这个系统,简单的单一继承并不是一个好办法。即使在PHP中有可能继承更多,但也有其固有的缺点(我不太了解,感觉很操蛋)。
Symfony EventDispatcher以一种简单有效的方式实现了中介器模式,事件Dispatcher就是中介器,这样系统和插件就不会耦合在一起,这就使得上面的插件系统成为可能,也会让你的项目更具扩展性。
以上文字翻译自Symfony官方文档片段
系统分析
事件存储
上图是通过分析Symfony EventDispatcher组件的源代码得到的,可以看到事件在系统中是如何存储的
在这种情况下,事件被存储两次,以增加优先级的概念。存放时放入上图上部结构,取出时从上图下部结构取出。同一事件名称可以有不同的优先级。优先级越高,优先级越高。当优先级相同时,首先触发第一个插入的事件。
插入事件时不会构建有序事件(上图下面的结构),取出事件时会生成有序事件。将新事件插入相同的事件名称或删除事件时,相应的有序事件名称将被删除,并在以后使用时重建。
当一个事件被执行时,对应于该事件名称的linster列表将被获取并按顺序执行。
事件执行
如上图所示,当触发某个时间时,如果在Event名称下监控到多个触发动作,则会按照优先级和注册顺序依次触发。触发器动作一般是一个可执行的“实例”(无论是类还是函数,都必须通过call_user_func_array调用),可以传入三个参数。第一个参数(必须)是事件实例,第二个参数被触发。第一个参数将控制事件是否继续在事件名称下的所有触发操作之间传递。例如,如果在上面的linstener_2中将Event.propagationStopped设置为true,则在执行linstener_2之后,事件将停止传播,并且不会触发linstener_2之后的操作。
此外,其他必要的信息可以保存在事件实例中,以便在linstener触发执行时获得额外的信息。
事件订阅者
事件订阅者告诉dispatcher实例,他想要订阅的所有事件不需要通过dispatcher实例逐一注册。事件订阅者是一个PHP类,它可以告诉dispathcer他想要订阅的特定事件。
好处:
感兴趣的事件不必一一登记。取消对事件的关注,而不逐个删除注册。订阅者关注的事件是一个整体,要么关注全部,要么不关注全部
例子
普通栗子
包括“vendor/autoload . PHP”;使用Symfony Component event dispatcher event dispatcher;使用Symfony Component Event dispatcher Event;类UserEvent扩展了Event { public function name(){ return ' Cartman ';}公共函数age(){ return ' 24 ';} } $ dispatcher=new event dispatcher();$ dispatcher-addListener(' user . name ',function($event,$eventName,$dispatcher){ echo '我叫Cartman n ';});$ dispatcher-addListener(' user . name ',function($event,$eventName,$dispatcher){ echo '我的名字是来自event实例的{ $ Event-name()} n ';}, 10);$ dispatcher-addListener(' user . age ',function($event,$eventName,$dispatcher){ echo '我的年龄是24 n ';}, 10);$ dispatcher-addListener(' user . age ',函数($event,$eventName,$dispatcher){ echo '我的年龄是来自event实例的{ $ Event-age()} n ';}, -10);$ dispatcher-dispatch(' user . name ',new user event());$dispatcher-dispatch('user.age ',new user event());以上示例输出
我的名字是来自事件实例的卡门我的名字是卡门我的年龄是24岁我的年龄是来自事件实例的24岁事件订阅者栗子
通过订户注册事件
包括“供应商/自动加载。PHP”;使用符号组件事件调度程序事件调度程序;使用符号组件事件调度程序事件;使用symfony Component event dispatcher event subscriber face;类BookEvent扩展了事件{ public $ name=self :类;}class BookSubscriber实现事件subscriber interface { public static function getSubscribedEvents(){ return[' Chinese。姓名'='中文姓名显示','英文。name '=['英文名show ',-10],['englishNameAFter ',10],],' math.name'=['mathNameShow ',100]];}公共函数中文名称显示(事件$ Event){ echo '我是汉语书籍 n ';}公共功能英语名称显示(事件$event) { echo '我是英文书籍 n ';}公共函数(Event $ Event){ echo '后的英文名称我是展示之后的英文书籍[来自于事件实例{ $ event-name }] n ';}公共函数mathNameShow(Event $event) { echo '我是展示的数学书籍 n ';} } $ dispatcher=new event dispatcher();$ subscriber=new BookSubscriber();$ dispatcher-addSubscriber($ subscriber);$ dispatcher-dispatch('英语。name ',new BookEvent());$ dispatcher-dispatch('中文。名称');$ dispatcher-删除订户($ subscriber);$ dispatcher-dispatch(' math。名称');输出为内容:
我是展示之后的英文书籍[来自于事件实例BookEvent]我是英文书籍我是汉语书籍以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持我们!