PHP实现行为事件

分类: 开发语言 > PHP

行为事件类:

<?php
class Event
{
    public $name;

    public $sender;

    public $handled = false;

    public $data = [];

    private static $_events = [];

    public static function on($class, $name, $handler, $data = null, $append = true)
    {
        $class = ltrim($class, '\\');
        if ($append || empty(self::$_events[$name][$class])) {
            self::$_events[$name][$class][] = [$handler, $data];
        } else {
            array_unshift(self::$_events[$name][$class], [$handler, $data]);
        }
    }

    public static function off($class, $name, $handler = null)
    {
        $class = ltrim($class, '\\');
        if (empty(self::$_events[$name][$class])) {
            return false;
        }
        if ($handler === null) {
            unset(self::$_events[$name][$class]);
            return true;
        } else {
            $removed = false;
            foreach (self::$_events[$name][$class] as $i => $event) {
                if ($event[0] === $handler) {
                    unset(self::$_events[$name][$class][$i]);
                    $removed = true;
                }
            }
            if ($removed) {
                self::$_events[$name][$class] = array_values(self::$_events[$name][$class]);
            }

            return $removed;
        }
    }

    public static function trigger($class, $name, $event = null)
    {
        if (empty(self::$_events[$name])) {
            return;
        }
        if ($event === null) {
            $event = new static;
        }
        $event->handled = false;
        $event->name = $name;

        if (is_object($class)) {
            if ($event->sender === null) {
                $event->sender = $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;
                    }
                }
            }
        }
    }
}

使用案例

<?php
require 'event.php';

class Object {
    public function on($name, $handle) {
        Event::on(get_class($this), $name, $handle[0], isset($handle[1]) ? $handle[1] : []);
    }

    public function off($name, $handle) {
        Event::off(get_class($this), $name, $handle[0]);
    }

    public function trigger($name, $event = null) {
        Event::trigger(get_class($this), $name, $event);
    }
}

class UserCheck {
    public static function check($event) {
        echo "检查权限<br />";
    }
}

class UserNotice {
    public static function notice() {
        echo "用户通知<br />";
    }
}

class User extends Object {
    const BEFORE_LOGIN = 'before_login';
    const AFTER_LOGIN = 'after_login';

    public function __construct() {
        $this->on(self::BEFORE_LOGIN, ['UserCheck::check', array('test' => 1)]);
        $this->on(self::AFTER_LOGIN, ['UserNotice::notice']);
        $this->on(self::AFTER_LOGIN, [[$this, 'sendEmail']]);
        $this->on(self::AFTER_LOGIN, [[$this, 'addPoint']]);
    }

    public function register() {
        $this->trigger(self::BEFORE_LOGIN);
        echo "注册成功<br />";
        $this->off(self::AFTER_LOGIN, [[$this, 'sendEmail']]);
        $this->trigger(self::AFTER_LOGIN);
    }

    public function sendEmail() {
        echo "发送邮件<br />";
    }

    public function addPoint() {
        echo "赠送积分<br />";
    }
}

$user = new User();
$user->register();
来源:原创 发布时间:2022-07-13 12:46:37