首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 实现轻量级事件机制:观察者模式与回调管理

     編輯:PHP 綜合知識

核心代码

<?php
class Event {
    private $callbacks = [];
    private $holder;

    public function __construct() {
        $bt = debug_backtrace();
        if (count($bt) < 2) {
            $this->holder = null;
            return;
        }
        $this->holder = &$bt[1]['object']; // 绑定创建者对象
    }

    // 注册回调:支持闭包、[对象, 方法名] 数组
    public function attach() {
        $args = func_get_args();
        switch (count($args)) {
            case 1:
                if (is_callable($args[0])) {
                    $this->callbacks[] = $args[0];
                }
                break;
            case 2:
                if (is_object($args[0]) && is_string($args[1])) {
                    $this->callbacks[] = [$args[0], $args[1]];
                }
                break;
        }
    }

    // 触发事件:仅允许 holder 对象调用
    public function notify() {
        $bt = debug_backtrace();
        if ($this->holder && ((count($bt) >= 2 && $bt[count($bt)-1]['object'] !== $this->holder) || count($bt) < 2)) {
            throw new Exception('Notify can only be called in holder');
        }
        $args = func_get_args();
        foreach ($this->callbacks as $callback) {
            call_user_func_array($callback, $args);
        }
    }
}

使用示例

class User {
    public $onLogin;

    public function __construct() {
        $this->onLogin = new Event();
    }

    public function login($username) {
        // 业务逻辑...
        $this->onLogin->notify($username, time()); // 触发
    }
}

$user = new User();
// 注册监听器
$user->onLogin->attach(function($name, $time) {
    echo "用户 $name 于 $time 登录\n";
});
$user->onLogin->attach(new Logger(), 'logLogin'); // 对象方法

$user->login('张三'); // 输出: 用户 张三 于 1234567890 登录

设计亮点

  • 创建者绑定:构造函数通过 debug_backtrace 获取实例化对象,notify 仅允许该对象调用,防止外部随意触发。
  • 灵活回调:支持匿名函数、对象方法数组、静态方法字符串等所有 call_user_func_array 兼容形式。
  • 轻量无依赖:纯 PHP 实现,无需扩展,适合中小项目。

注意事项

  • debug_backtrace 有性能开销,高频调用场景建议改用显式传递 $holder。
  • PHP 7.1+ 推荐使用 Closure::fromCallable 统一回调格式。
  • 大型项目可考虑 Symfony EventDispatcher、Laravel Events 等成熟组件。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved