ecfectus / events
PHP7 事件调度器
Requires
- php: >=7.0.0
- php-ds/php-ds: ^1.1
Requires (Dev)
- phpdocumentor/phpdocumentor: 2.*
- phpunit/phpunit: ^5.5.0
This package is not auto-updated.
Last update: 2024-09-18 18:18:27 UTC
README
PHP7 事件调度器,利用新的类型提示和 Ds\PriorityQueue
数据类型,以提高性能和降低复杂性。
使用方法
使用方法简单,使用 listen
添加回调,使用 fire
运行事件回调。
class TestEvent extends Ecfectus\Events\Event{ public $value = []; } $dispatcher = new Ecfectus\Events\Dispatcher(); $dispatcher->listen(TestEvent::class, function(Event $e){ $e->value[] = 2; }, 500); $dispatcher->listen(TestEvent::class, function(Event $e){ $e->value[] = 1; }, 1); $result = $dispatcher->fire(new TestEvent()); $result->value will equal [2, 1]
通配符监听器
您还可以添加通配符事件,并且事件的优先级将得到保持。
$dispatcher->listen('TestEv*', function(Event $e){ $e->value[] = 3; }, 100); $dispatcher->listen('*', function(Event $e){ $e->value[] = 4; }, -10); $result = $dispatcher->fire(new TestEvent()); $result->value will equal [2, 3, 1, 4]
回调
默认情况下,回调可以是任何 callable
,有关可用性的详细信息,请参阅此处 php 文档: https://php.ac.cn/manual/en/language.types.callable.php
此外,您可以设置一个解析器,当回调不可调用时,该解析器将被调用,这对于使用容器创建对象很有用。
例如,以 Laravel 风格提供事件监听器可以像这样实现
$dispatcher->setResolver(function($callback = null){ //return a function that can be invoked return function(Event $e) use ($callback){ //parse the callback into something that can be used list($class, $method) = explode('@', $callback); $instance = $somecontainer->make($class); //return the result of the method return $instance->$method($event); }; }); $dispatcher->listen('*', 'MyClassName@handleEvent', -10);//MyClassName is created via the resolver and the result of the handleEvent method is returned.
忘记事件
您可以通过调用 forgot
调度器方法来移除事件的所有监听器。
$dispatcher->forget(TestEvent::class); all listeners for TestEvent will be forgotten $dispatcher->forget('*'); all listeners for the wildcard * will be forgotten
事件
事件应扩展 Ecfectus\Events\Event
类,除此之外,事件可以按您希望的方式实现。
核心事件类仅提供对调度器进行类型提示的基础,您可以在事件中包含或添加您想要的任何功能。
在将来,我们可能会添加传播功能或其他尚未确定的功能,而不是让您更改代码,我们可以将这些功能添加到核心事件类中。
为什么不允许字符串事件名称?
我们考虑了这个问题一段时间,并得出结论,使用事件名称作为类的字符串表示形式是最佳解决方案,原因有很多。
- 检查事件名称的类型和值的样板代码被简化为简单的
class_name
调用。 - 我们知道传入和传递给调度器的确切内容,因此我们可以相应地进行类型提示。
- IDE 和自动完成使开发者更容易,而不是记住字符串值。
- 在某些情况下,添加“灵活性”只会使文档更加混乱,特别是当在一个项目中,一个开发者更喜欢一种风格而不是另一种风格时,用户会感到困惑。
这样非常简单,您只需传入您的事件实例即可。
订阅者
您还可以创建订阅者类并将它们添加到调度器中,这些类必须提供 subscribe
方法,并将调度器实例传递给它们。
在订阅者的 subscribe
方法内部,您可以使用调度器作为正常操作,这对于分组事件监听器非常完美。
class NameOfSubscriberClass{ public function subscribe($dispatcher) { $dispatcher->listen('*', function(Event $e){ $e->value[] = 1; }); $dispatcher->listen('*', function(Event $e){ $e->value[] = 2; }); //more events } } $dispatcher->subscribe('NameOfSubscriberClass');// NameOfSubscriberClass will be created for you via (new NameOfSubscriberClass()) //or pass an instance (ideal if your subscriber needs constructor arguments) $subscriber = new NameOfSubscriberClass(); $dispatcher->subscribe($subscriber);