以下是Component小demo。
<?php
class Event {
public $name;
public $data;
}
abstract class Component {
private static $_events = [];
public function on($name, $handler, $data = null) {
self::$_events[$name][] = [$handler, $data];
}
public function trigger($name) {
$event = new Event;
$event->name = $name;
foreach (self::$_events[$name] as $handler) {
// 构造event
$event->data = $handler[1];
call_user_func($handler[0], $event);
}
}
}
class Person extends Component {
const EVENT_HELLO = 0;
public function hello($event) {
echo "hello: ".$event->data."\n";
}
}
$myComponent = new Person();
$myComponent->on(Person::EVENT_HELLO, [$myComponent, 'hello'], " lee");
$myComponent->trigger(Person::EVENT_HELLO);
###########
在trigger的时候,动态绑定一个数据。
<?php
class Event {
public $name;
public $data;
}
abstract class Component {
private static $_events = [];
public function on($name, $handler, $data = null) {
self::$_events[$name][] = [$handler, $data];
}
public function trigger($name, $event = null) {
if ($event === null) {
public $data;
}
abstract class Component {
private static $_events = [];
public function on($name, $handler, $data = null) {
self::$_events[$name][] = [$handler, $data];
}
public function trigger($name, $event = null) {
if (!empty(self::$_events[$name])) {
if ($event === null) {
$event = new static;
<?php
class Event {
public $name;
public $data;
}
abstract class Component {
private static $_events = [];
public function on($name, $handler, $data = null) {
self::$_events[$name][] = [$handler, $data];
}
public function trigger($name, $event = null) {
if (!empty(self::$_events[$name])) {
if ($event === null) {
$event = new static;
}
$event->name = $name;
foreach (self::$_events[$name] as $handler) {
$event->data = $handler[1];
call_user_func($handler[0], $event);
}
}
}
}
class Person extends Component {
const EVENT_HELLO = 0;
public function hello($event) {
echo "hello: ".$event->data."\n";
echo "publicTime: ".$event->publicTime."\n";
}
}
$myComponent = new Person();
$publicEvent = new Event;
$publicEvent->publicTime = '2016-05-21 14:39:05';
$myComponent->on(Person::EVENT_HELLO, [$myComponent, 'hello'], " lee");
$myComponent->trigger(Person::EVENT_HELLO, $publicEvent);
##############
在event添加是否handled字段,如果设定为handled=true, 则不继续处理。
<?php
class Event {
public $name;
public $data;
public $handled;
}
abstract class Component {
private static $_events = [];
public function on($name, $handler, $data = null) {
self::$_events[$name][] = [$handler, $data];
}
public function trigger($name, $event = null) {
if (!empty(self::$_events[$name])) {
if ($event === null) {
class Event {
public $name;
public $data;
public $handled;
}
abstract class Component {
private static $_events = [];
public function on($name, $handler, $data = null) {
self::$_events[$name][] = [$handler, $data];
}
public function trigger($name, $event = null) {
if (!empty(self::$_events[$name])) {
if ($event === null) {
$event = new static;
}
$event->name = $name;
$event->handled = false; // 设置时间未处理
foreach (self::$_events[$name] as $handler) {
$event->data = $handler[1];
call_user_func($handler[0], $event);
if ($event->handled) { // 如果handler 设置handled为true,表示不继续处理下去
return;
}
}
}
}
}
class Person extends Component {
const EVENT_HELLO = 0;
public function hello($event) {
echo "hello: ".$event->data."\n";
echo "publicTime: ".$event->publicTime."\n";
// 设置不继续处理下去
$event->handled = true;
}
}
$myComponent = new Person();
$publicEvent = new Event;
$publicEvent->publicTime = '2016-05-21 14:39:05';
$myComponent->on(Person::EVENT_HELLO, [$myComponent, 'hello'], " lee");
$myComponent->trigger(Person::EVENT_HELLO, $publicEvent);
################
class-level event
类级别事件,不是由某个类的实例来注册,而是由类来注册,这样,所有类的实例都能够处理这个事件。
<?php
class Event {
public $name;
public $data;
public $handled;
// global class-level Events
private static $_events = [];
// 归属于那个类
public static function on($class, $name, $handler, $data = null) {
$class = ltrim($class, '\\');
if (empty(self::$_events[$name])) {
self::$_events[$name][$class][] = [$handler, $data];
} else {
array_unshift(self::$_events[$name][$class], [$handler, $data]);
}
}
public static function trigger($class, $name, $event = null) {
if (empty(self::$_events[$name])) {
return;
}
if ($event === null) {
$event = new static;
}
$event->name = $name;
$event->handled = false;
if (is_object($class)) {
$class = get_class($class);
} else {
$class = ltrim($class, '\\');
}
// 获取所有父类,子类,当前类
$classes = array_merge(
[$class],
class_parents($class, true),
class_implements($class, true)
);
foreach ($classes as $class) {
if (!empty(self::$_events[$name][$class])) {
foreach (self::$_events[$name][$class] as $handler) {
$event->data = $handler[1];
call_user_func($handler[0], $event);
if ($event->handled) {
return;
}
}
}
}
}
}
abstract class Component {
private static $_events = [];
public function on($name, $handler, $data = null) {
self::$_events[$name][] = [$handler, $data];
}
public function trigger($name, $event = null) {
if (!empty(self::$_events[$name])) {
if ($event === null) {
$event = new static;
}
$event->name = $name;
$event->handled = false;
foreach (self::$_events[$name] as $handler) {
$event->data = $handler[1];
call_user_func($handler[0], $event);
if ($event->handled) {
return;
}
}
}
// 是否有类全局事件处理
Event::trigger($this, $name, $event);
}
}
class Person extends Component {
const EVENT_HELLO = 0;
public static function hello($event) {
echo "hello: ".$event->data."\n";
echo "publicTime: ".$event->publicTime."\n";
$event->handled = true;
}
}
Event::on('Person', Person::EVENT_HELLO, ['Person', 'hello'], " lee");
$myComponent = new Person();
$publicEvent = new Event;
$publicEvent->publicTime = '2016-05-21 14:39:05';
$myComponent->trigger(Person::EVENT_HELLO, $publicEvent);
只需要全局注册一个事件,类的实例都可以使用这个事件了。
其他细节,如off等,参考yii的源码