Skip to content

Commit ae4823f

Browse files
committed
事件监听器支持:匿名函数和对象实例
1 parent f96b896 commit ae4823f

File tree

4 files changed

+39
-30
lines changed

4 files changed

+39
-30
lines changed

README.md

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,7 @@ Soli Event Manager
3737
echo "应用已启动\n";
3838
});
3939

40-
`监听器的格式`,只要是 [call_user_func_array] 允许的格式即可,
41-
也可以是包含与事件名称同名的实例化类。
40+
`监听器的格式`,可以是 `匿名函数或对象实例`
4241

4342
如,我们这里定义一个 `AppEvents` 类用于处理针对 `Application` 类的事件:
4443

@@ -56,11 +55,14 @@ Soli Event Manager
5655
}
5756

5857
// 注册事件监听
59-
$eventManager->on('application:boot', array(new AppEvents, 'boot'));
60-
也可以这样:
61-
$eventManager->on('application:boot', new AppEvents);
6258

63-
或 call_user_func_array 支持的其他格式。
59+
// 匿名函数
60+
$eventManager->on('application:boot', function (Event $event, $application) {
61+
echo "应用已启动\n";
62+
});
63+
64+
// 对象实例
65+
$eventManager->on('application:boot', new AppEvents);
6466

6567
### 聚合事件监听器到专门的事件类中进行处理
6668

@@ -70,7 +72,7 @@ Soli Event Manager
7072

7173
$eventManager->on('application', new AppEvents);
7274

73-
这样我们便可以很方便的注册和整理不同纬度的不同事件
75+
这样我们便可以很方便的注册和整理不同维度的不同事件
7476

7577
### 触发事件
7678

@@ -97,5 +99,4 @@ Soli Event Manager
9799
MIT Public License
98100

99101

100-
[Phalcon 框架的事件管理器]: https://docs.phalconphp.com/zh/latest/reference/events.html
101-
[call_user_func_array]: http://cn2.php.net/call_user_func_array
102+
[Phalcon 框架的事件管理器]: https://docs.phalconphp.com/en/latest/events

src/Events/Event.php

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
*/
55
namespace Soli\Events;
66

7+
use Closure;
8+
79
/**
810
* 事件原型
911
*/
@@ -80,18 +82,12 @@ public function fire($queue)
8082
break;
8183
}
8284

83-
if (is_callable($listener)) {
85+
if ($listener instanceof Closure) {
86+
// 调用闭包监听器
8487
$status = call_user_func_array($listener, [$this, $this->source, $this->data]);
85-
} elseif (is_object($listener)) {
86-
if (method_exists($listener, $this->name)) {
87-
// 调用对象监听器
88-
$status = $listener->{$this->name}($this, $this->source, $this->data);
89-
}
90-
} elseif (is_string($listener) && class_exists($listener)) {
91-
// 注意这里的 $this->name 需要是 $listener 的静态方法
92-
if (method_exists($listener, $this->name)) {
93-
$status = call_user_func_array([$listener, $this->name], [$this, $this->source, $this->data]);
94-
}
88+
} elseif (method_exists($listener, $this->name)) {
89+
// 调用对象监听器
90+
$status = $listener->{$this->name}($this, $this->source, $this->data);
9591
}
9692
}
9793

src/Events/EventManager.php

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,16 @@
1212
*
1313
*<pre>
1414
* $eventManager = new \Soli\Events\EventManager();
15-
* // 将针对 "dispatch" 分组的事件监听器,统一整理到 DispatchEvents 类,一并注册
16-
* $eventManager->on('dispatch', new DispatchEvents);
1715
*
1816
* // 注册具体的某个事件监听器
19-
* $eventManager->on('application:boot', array(new AppEvents, 'boot'));
17+
* $eventManager->on('application:boot', function (\Soli\Events\Event $event, $application) {
18+
* echo "应用已启动\n";
19+
* });
2020
*
21-
* // 触发事件
22-
* $eventManager->fire('dispatch:beforeDispatchLoop', $this);
21+
* // 也可以将针对 "application" 的事件统一整理到 AppEvents 类,一并注册
22+
* $eventManager->on('application', new AppEvents);
23+
*
24+
* // 触发某个具体事件
2325
* $eventManager->fire('application:boot', $this);
2426
*</pre>
2527
*/
@@ -39,11 +41,9 @@ class EventManager implements EventManagerInterface
3941
* 有分号则认为是为具体的某个事件添加监听器
4042
* 此规则会在 fire 方法中体现
4143
*
42-
* 关于 callable: @see http://cn2.php.net/manual/zh/language.types.callable.php#example-111
43-
*
4444
* @param string $name 事件名称,格式为:「事件分组类型:事件名称」
4545
* 可以是事件分组类型,也可以是完整的事件名称
46-
* @param object|callable|string $listener 监听器(对象、callable、类名
46+
* @param \Closure|object $listener 监听器(匿名函数、对象实例
4747
*/
4848
public function on($name, $listener)
4949
{

tests/Events/EventManagerTest.php

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
class EventManagerTest extends TestCase
1010
{
11-
public function testFire()
11+
public function testFireByClosure()
1212
{
1313
$eventManager = new EventManager;
1414
// 监听事件
@@ -19,6 +19,18 @@ function (Event $event, $myComponent) {
1919
}
2020
);
2121

22+
$myComponent = new MyComponent;
23+
$myComponent->setEventManager($eventManager);
24+
25+
$result = $myComponent->someTask();
26+
27+
$this->assertStringStartsWith('before, do something', $result);
28+
}
29+
30+
public function testFireByInstance()
31+
{
32+
$eventManager = new EventManager;
33+
2234
$eventManager->on(
2335
'my-component',
2436
new MyComponentEvents
@@ -29,7 +41,7 @@ function (Event $event, $myComponent) {
2941

3042
$result = $myComponent->someTask();
3143

32-
$this->assertStringStartsWith('before, do something', $result);
44+
$this->assertStringEndsWith('do something, after', $result);
3345
}
3446
}
3547

0 commit comments

Comments
 (0)