maximebf / events
PHP5.3 的事件库
Requires
- php: >=5.3.0
This package is not auto-updated.
Last update: 2024-05-25 10:55:23 UTC
README
PHP 5.3+ 的事件库
事件提供了一种事件调度器,可以通过多种方式监听事件。
$dispatcher = new Events\EventDispatcher();
$dispatcher->on('car.forward', function($e) {
echo "The car is goind forward";
});
$dispatcher->notify(new Events\Event(null, 'car.forward'));
查看 example.php 以获得完整示例。
安装
安装 Events 最简单的方式是使用 Composer,以下为所需要求
{
"require": {
"maximebf/events": ">=1.0.0"
}
}
或者,您可以 下载存档,并将 src/ 文件夹添加到 PHP 的 include 路径
set_include_path('/path/to/src' . PATH_SEPARATOR . get_include_path());
Events 不提供自动加载器,但遵循 PSR-0 规范。
您可以使用以下代码片段来自动加载 Events 类
spl_autoload_register(function($className) {
if (substr($className, 0, 6) === 'Events') {
$filename = str_replace('\\', DIRECTORY_SEPARATOR, trim($className, '\\')) . '.php';
require_once $filename;
}
});
监听事件
事件通过 Events\EventDispatcher
类进行通知。注册监听器以处理事件的简单方法是使用 on()
方法
on($event_name, $callback)
:监听指定名称的事件,可以使用通配符(*
)字符on($regexp, $callback)
:监听名称与正则表达式匹配的事件on($callback)
:监听所有事件on($object)
:使用对象的 "on" 方法进行监听(见下文)
$callback
可以是任何 PHP 可调用函数(即回调 - 字符串或数组 - 或闭包)。它将只接收一个 Events\Event
对象作为其唯一参数。
$dispatcher->on('car.forward', function($e) {});
$dispatcher->on('car.*', function($e) {});
$dispatcher->on('/^car\.(.+)$/', function($e) {});
$dispatcher->on(function($e) {});
当使用 on($object)
时,该对象应具有以驼峰式命名的、以 "on" 开头的方法。例如:方法 onCarForward()
将监听名为 car.forward(或 car_forward 或 car-forward)的事件。
class CarListener {
public function onCarForward($e) {}
}
$dispatcher->on(new CarListener());
多个监听器可以监听同一事件。但是,其中一些可能比其他更重要。这可以通过将整数作为 on()
方法的第三个参数来指定。数值越高,重要性越大。
$dispatcher->on('car.forward', function($e) {}, 100);
事件由发送者、名称和一些参数组成。事件对象有以下方法
getSender()
:返回发出事件的对象getName()
:返回事件的名称getParam($name, $default=null)
:返回 $name 参数getParams()
对于某些事件,可能需要返回值。监听器可以使用 setReturnValue($value)
指定返回值。
某些事件可能允许取消它们所代表的操作。这可以通过使用 cancel()
来执行。
最后,如果多个监听器处理一个事件,其中一个可以使用 stopPropagation()
停止事件传播到其他监听器。
$dispatcher->on('method_call', function($e) {
if ($e->getParam('method_name') === 'foobar') {
$e->cancel();
} else {
$e->setReturnValue(true);
}
});
在底层,当调用 on()
方法时,事件调度器会创建一个类型为 Events\EventListener
的监听器对象。您可以创建自定义监听器对象,并使用 addListener()
添加它们。
调度事件
可以使用事件调度器的 notify($event)
方法调度事件。事件必须是类型为 Events\Event
的对象。
$dispatcher->notify(new Events\Event($sender, $name, $params));
notify()
返回一个布尔值,指示事件是否被一个或多个监听器处理。
如果您想确保事件至少被一个监听器接收,可以使用 notifyUntil($event, $callback=null)
。此方法将尝试传递事件,如果失败,将尝试与未来添加的任何监听器。当事件被处理时,将调用 $callback
。
$dispatcher->notifyUntil(new Events\Event(null, 'foo'), function() {
echo "Event processed!";
});
为了简化事件通知的过程,可以使用Events\Notifier
对象来创建和分发事件。它的构造函数需要传入事件分发器和发送者对象作为必选参数。您可以可选地提供事件名称的前缀,并指定使用不同的事件类。提供的方法有notify()
和notifyUntil()
,但它们的形式略有不同。它们不是接收事件对象,而是接收事件名称以及可选的参数数组。
$notifier = new Events\Notifier($eventDispatcher, $sender);
$notifier->notify('foobar', array('param1' => 'value'));
其他实用工具
您可以使用Events\GenericEmitter
创建可以发射事件的对象,并在此对象上注册监听器。
class Car extends Events\GenericEmitter {
protected $eventPrefix = 'car.';
public function forward() {
$this->notify('forward');
}
}
$car = new Car();
$car->on('car.forward', function($e) {});
事件发射器可以充当中继器。因此,如果您有一个全局事件分发器,可以通过将特定发射器作为监听器添加到全局事件分发器中,来中继该发射器的事件。
$car = new Car();
$dispatcher = new Events\EventDispatcher();
$car->on('car.forward', function($e) {});
$dispatcher->on('car.forward', function($e) {});
$car->addListener($dispatcher);
可以使用Events\EventProxy
类作为任何对象的代理,并且每当访问属性或调用方法时,都会发射事件。
$object = new Events\EventProxy(new MyClass(), $dispatcher);
$dispatcher->on('proxy.call', function($e) {
if ($e->getParam('method') === 'foobar') {
echo "Foobar was called!";
}
});
$object->foobar();
您可以通过实现Events\EventListener
接口来创建自定义事件监听器。
class CustomListener implements Events\EventListener {
public function match(Event $e) {
// checks if the event can be handled by this listener
return $e->getName() === 'foobar';
}
public function handle(Event $e) {
// do something with $e when match() returned true
echo $e->getName();
}
}
$dispatcher->addListener(new CustomListener());