今天,我们将学习如何使用 Symfony 事件调度程序组件,它允许您在 PHP 应用程序中创建事件和侦听器。因此,应用程序的不同组件可以通过松散耦合的代码相互通信。
什么是 Symfony 事件调度程序组件?
您可能熟悉事件观察者模式,它允许您为系统生成的事件定义侦听器,以便在触发事件时执行它们。类似地,Symfony EventDispatcher 组件允许您设置一个可以在其中创建自定义事件和侦听器的系统。通过这种方式,您可以允许应用程序中的组件在系统中发生某些情况时做出反应。
事实上,事件调度程序组件提供了三个元素,您可以围绕它们构建应用程序架构:事件、侦听器和调度程序。整个系统由调度程序类编排,它在应用程序中的适当点引发事件并调用与这些事件关联的侦听器。
假设您希望允许应用程序中的其他组件在缓存被清除时做出反应。在这种情况下,您需要首先定义清除缓存事件。清除缓存后,您可以使用调度程序引发清除缓存事件,并通知所有正在侦听此事件的侦听器。这使侦听器有机会清除特定于组件的缓存。
在本文中,我们将探讨事件调度程序组件的基础知识。我们将从安装和配置开始,我们还将创建一些实际示例来演示上述所有概念。
安装和配置事件调度程序
在本节中,我们将安装事件调度程序组件。我假设您已经在系统上安装了 Composer,因为我们需要它来安装 EventDispatcher 组件。
安装 Composer 后,请继续使用以下命令安装 EventDispatcher 组件。
1 |
$composer需要 symfony/事件调度程序 |
这应该已经创建了composer.json文件,该文件应如下所示:
1 |
{ |
2 |
“要求” : { |
3 |
“ symfony/事件调度程序” : “ ^5.4 ” |
4 |
} |
5 |
} |
让我们进一步编辑composer.json文件,如下所示:
1 |
{ |
2 |
“要求” : { |
3 |
“ symfony/事件调度程序” : “ ^5.4 ” |
4 |
}, |
5 |
“自动加载” : { |
6 |
“ psr-4 ” : { |
7 |
“ EventDispatchers \\ ” : “ src ” |
8 |
}, |
9 |
“类映射” : [ “ src ” ] |
10 |
} |
11 |
} |
由于我们添加了新的类映射条目,请继续通过运行以下命令来更新 Composer 自动加载器。
1 |
$composer转储-o |
现在,您可以使用EventDispatchers
命名空间自动加载src目录下的类。
这就是安装部分,但是你应该如何使用它呢?事实上,只需将Composer 创建的autoload.php文件包含在您的应用程序中即可,如以下代码片段所示。
1 |
<?php |
2 |
require_once './vendor/autoload.php' ; |
3 |
|
4 |
// 应用代码 |
5 |
?> |
如何创建、调度和监听事件
在本节中,我们将通过一个示例演示如何创建自定义事件并为该事件设置侦听器。
事件类
首先,继续创建包含以下内容的src/Events/DemoEvent.php文件。
1 |
<?php |
2 |
命名空间 EventDispatchers\Events ; |
3 |
|
4 |
使用 Symfony\Contracts\EventDispatcher\Event ; |
5 |
|
6 |
类 DemoEvent 扩展了 Event |
7 |
{ |
8 |
const NAME = 'demo.event' ; |
9 |
|
10 |
受保护的 $foo ; |
11 |
|
12 |
公共 函数 __construct () |
13 |
{ |
14 |
$this -> foo = 'bar' ; |
15 |
} |
16 |
|
17 号 |
公共 函数 getFoo () |
18 |
{ |
19 |
返回 $this -> foo ; |
20 |
} |
21 |
} |
我们的自定义类扩展了EventDispatcher 组件的DemoEvent
核心类。Event
该NAME
常量保存我们的自定义事件的名称-demo.event
。当您想为此事件设置侦听器时使用它。
聆听者阶层
接下来,让我们使用以下内容创建监听器类src/Listeners/DemoListener.php 。
1 |
<?php |
2 |
命名空间 EventDispatchers\Listeners ; |
3 |
|
4 |
使用 Symfony\Contracts\EventDispatcher\Event ; |
5 |
|
6 |
类 演示监听器 |
7 |
{ |
8 |
公共 函数 onDemoEvent (事件 $event ) |
9 |
{ |
10 |
// 在这里获取事件信息 |
11 |
echo "DemoListener 被调用!\n " ; |
12 |
echo "foo 的值为:" 。$event -> getFoo () 。“ \n ” ; |
13 |
} |
14 |
} |
该类DemoListener
实现了onDemoEvent
系统调度DemoEvent
事件时触发的方法。当然,它还不会自动发生,因为我们需要注册侦听器以使用类DemoListener
侦听事件。demo.event
EventDispatcher
到目前为止,我们已经创建了事件和侦听器类。接下来,我们将了解如何将所有这些部分连接在一起。
示例文件
让我们创建包含以下内容的basic_example.php文件。
1 |
<?php |
2 |
// basic_example.php |
3 |
|
4 |
require_once './vendor/autoload.php' ; |
5 |
使用 Symfony\Component\EventDispatcher\EventDispatcher ; |
6 |
使用 EventDispatchers\Events\DemoEvent ; |
7 |
使用 EventDispatchers\Listeners\DemoListener ; |
8 |
|
9 |
// 初始化事件调度程序 |
10 |
$dispatcher = new EventDispatcher (); |
11 |
|
12 |
// 注册 'demo.event' 事件的监听器 |
13 |
$listener = new DemoListener (); |
14 |
$dispatcher -> addListener ( 'demo.event' , array ( $listener , 'onDemoEvent' )); |
15 |
|
16 |
// 派遣 |
17 号 |
$dispatcher -> dispatch ( new DemoEvent (), DemoEvent :: NAME ); |
该类EventDispatcher
是 EventDispatcher 组件中最重要的元素 — 它允许您将侦听器绑定到它们想要侦听的事件。我们使用类addListener
的方法EventDispatcher
来监听事件demo.event
。
该方法的第一个参数addListener
是在分派注册事件时触发的 PHP 可调用函数,第二个参数是事件名称。在我们的例子中,我们提供了DemoListener
对象作为侦听器以及onDemoEvent
方法。
1 |
$dispatcher -> addListener ( 'demo.event' , array ( $listener , 'onDemoEvent' )); |
最后,我们使用dispatch
该类的方法EventDispatcher
来调度demo.event
事件。
1 |
$dispatcher ->调度( DemoEvent :: NAME , new DemoEvent ()); |
当您运行basic_example.php文件时,它应该产生以下输出。
1 |
$php basic_example.php |
2 |
DemoListener 被调用! |
3 |
foo 的值为:bar |
正如预期的那样,类onDemoEvent
的方法被调用,类的方法DemoListener
又调用类的方法来获取与事件相关的信息。getFoo
DemoEvent
什么是事件订阅者?
在上一节中,我们构建了一个示例,演示了如何创建自定义事件和自定义侦听器。我们还讨论了如何使用该类将侦听器绑定到特定事件EventDispatcher
。
这是一个简单的示例,因为我们只想为单个事件设置侦听器。另一方面,如果您想要为多个事件设置侦听器,或者想要在逻辑上将事件处理逻辑分组到单个类中,则应该考虑使用事件订阅者,因为它们允许您将所有内容保留在一个位置。
在本节中,我们将修改上一节中创建的示例。
订阅者类别
我们需要做的第一件事是创建一个实现该EventSubscriberInterface
接口的订阅者类。继续创建src/Subsribers/DemoSubscriber.php类,如以下代码片段所示。
1 |
<?php |
2 |
命名空间 EventDispatchers\Subscribers ; |
3 |
|
4 |
使用 Symfony\Component\EventDispatcher\EventSubscriberInterface ; |
5 |
使用 EventDispatchers\Events\DemoEvent ; |
6 |
|
7 |
类 DemoSubscriber 实现 EventSubscriberInterface |
8 |
{ |
9 |
公共 静态 函数 getSubscribedEvents () |
10 |
{ |
11 |
返回 数组( |
12 |
演示事件::名称 => 'onDemoEvent' , |
13 |
); |
14 |
} |
15 |
|
16 |
公共 函数 onDemoEvent ( DemoEvent $event ) |
17 号 |
{ |
18 |
// 在这里获取事件信息 |
19 |
echo "DemoListener 被调用!\n " ; |
20 |
echo "foo 的值是:" 。$event -> getFoo () 。“ \n ” ; |
21 |
} |
22 |
} |
既然类DemoSubscriber
实现了EventSubscriberInterface
接口,那么它就必须实现getSubscribedEvents
方法。该getSubscribedEvents
方法应返回您要订阅的事件数组。您需要在数组键中提供事件名称,并在触发事件时调用的数组值中提供方法名称。
最后一件事是在同一个类中实现监听器方法。在我们的例子中,我们需要实现该onDemoEvent
方法,并且我们已经做到了。
示例文件
是时候测试我们的订阅者了!让我们快速创建包含以下内容的subscriber_example.php文件。
1 |
<?php |
2 |
require_once './vendor/autoload.php' ; |
3 |
使用 Symfony\Component\EventDispatcher\EventDispatcher ; |
4 |
使用 EventDispatchers\Subscribers\DemoSubscriber 作为 DemoSubscriber ; |
5 |
使用 EventDispatchers\Events\DemoEvent ; |
6 |
|
7 |
// 初始化事件调度程序 |
8 |
$dispatcher = new EventDispatcher (); |
9 |
|
10 |
// 注册订阅者 |
11 |
$subscriber = new DemoSubscriber (); |
12 |
$dispatcher -> addSubscriber ( $subscriber ); |
13 |
|
14 |
// 派遣 |
15 |
$dispatcher -> dispatch ( new DemoEvent (), DemoEvent :: NAME ); |
您需要使用addSubscriber
该类的方法EventDispatcher
来订阅您的自定义订阅者,该类EventDispatcher
会处理其余的事情。它从方法中获取要订阅的事件getSubscribedEvents
,并为这些事件设置侦听器。除此之外,一切都是一样的,并且应该按预期工作,不会有任何意外。
我们来测试一下吧!
1 |
$ phpsubscriber_example.php |
2 |
DemoListener 被调用! |
3 |
foo 的值为:bar |
这就是您可以使用的事件订阅者!这也让我们来到了本文的结尾。
如何停止事件传播
有时,多个侦听器正在侦听同一个事件。在这种情况下,您可能希望停止将事件传播到下一个后续侦听器。在本节中,我们将了解如何在听众的帮助下实现这一目标。
让我们回顾一下之前创建的侦听器类。
1 |
<?php |
2 |
命名空间 EventDispatchers\Listeners ; |
3 |
|
4 |
使用 Symfony\Contracts\EventDispatcher\Event ; |
5 |
|
6 |
类 演示监听器 |
7 |
{ |
8 |
公共 函数 onDemoEvent (事件 $event ) |
9 |
{ |
10 |
// 在这里获取事件信息 |
11 |
echo "DemoListener 被调用!\n " ; |
12 |
echo "foo 的值为:" 。$event -> getFoo () 。“ \n ” ; |
13 |
$event -> stopPropagation (); |
14 |
} |
15 |
} |
正如您所看到的,我们使用该stopPropagation
方法来停止事件传播。这意味着正在侦听demo.event
事件但尚未被调用的侦听器将不会被调用。所以这是为此事件调用的最后一个侦听器。您还可以使用该isPropagationStopped
方法来检测事件传播是否被任何侦听器停止。
如何使用 PHP 闭包作为监听器
到目前为止,我们已经讨论了如何将 PHP 对象添加为侦听器。事实上,你也可以使用 PHP 闭包来代替 PHP 对象。
让我们快速修改一下前面的示例。
1 |
<?php |
2 |
require_once './vendor/autoload.php' ; |
3 |
使用 Symfony\Component\EventDispatcher\EventDispatcher ; |
4 |
使用 EventDispatchers\Events\DemoEvent ; |
5 |
|
6 |
// 初始化事件调度程序 |
7 |
$dispatcher = new EventDispatcher (); |
8 |
|
9 |
// 为 'demo.event' 事件注册闭包监听器 |
10 |
$dispatcher -> addListener ( 'demo.event' , function ( DemoEvent $event ) { |
11 |
echo "DemoListener 被调用!\n " ; |
12 |
echo "foo 的值为:" 。$event -> getFoo () 。“ \n ” ; |
13 |
}); |
14 |
|
15 |
// 派遣 |
16 |
$dispatcher- > dispatch ( new DemoEvent (), 'demo.event' ); |
正如您所看到的,我们在该addListener
方法的第二个参数中使用了 PHP 闭包。
结论
今天,我们探索了 Symfony 事件调度程序组件,它允许您在 PHP 应用程序中设置事件和侦听器。通过使用此库,您可以创建一个松散耦合的系统,该系统允许应用程序的组件轻松地相互通信。
via https://code.tutsplus.com/handling-events-in-your-php-applications-using-the-symfony-eventdispatcher-component--cms-31328t