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

PHP 實作事件機制:基於 debug_backtrace 的觀察者模式進階應用

     編輯:PHP 相關知識

PHP 實作事件機制:基於 debug_backtrace 的觀察者模式進階應用

PHP 核心未內建事件/觀察者機制,但透過 debug_backtrace() 可實現「只有直接持有事件對象的呼叫者才能觸發」的限制,構建更安全的事件系統。本文解析一個完整的 Event 類別實作。

核心設計思路

  • 附加監聽器:支援閉包、[$object, 'method'] 陣列兩種回呼形式。
  • 觸發限制:建構子記錄 holder(直接持有者),notify() 時檢查呼叫堆疊底部是否為該 holder,否則拋出異常。
  • 參數透傳:notify() 將所有參數原樣傳給每個監聽器。

完整類別程式碼

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

    public function __construct() {
        $bt = debug_backtrace();
        $this->holder = (count($bt) >= 2) ? $bt[1]['object'] : null;
    }

    public function attach() {
        $args = func_get_args();
        if (count($args) === 1 && is_callable($args[0])) {
            $this->callbacks[] = $args[0];
        } elseif (count($args) === 2 && is_object($args[0]) && is_string($args[1])) {
            $this->callbacks[] = [$args[0], $args[1]];
        }
    }

    public function notify() {
        $bt = debug_backtrace();
        // 檢查呼叫者是否為直接持有者
        if ($this->holder && (count($bt) < 2 || end($bt)['object'] !== $this->holder)) {
            throw new Exception('Notify can only be called by holder');
        }
        $args = func_get_args();
        foreach ($this->callbacks as $cb) {
            call_user_func_array($cb, $args);
        }
    }
}
?>

使用範例

class Order {
    public $onShipped;

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

    public function ship() {
        // 業務邏輯...
        $this->onShipped->notify($this, 'shipped'); // 只有 Order 實例能觸發
    }
}

$order = new Order();
$order->onShipped->attach(function($order, $status) {
    echo "訂單 {$order->id} 已{$status},發送通知郵件。";
});
$order->ship(); // 正常觸發

// 外部嘗試觸發會拋出異常
// $order->onShipped->notify(); // Exception: Notify can only be called by holder

優缺點與替代方案

優點缺點
強制封裝觸發權限,符合「事件屬於物件」語意debug_backtrace 效能較低,高頻觸發場景不適用
無需額外擴展,純 PHP 實作堆疊檢查在某些 PHP 版本/配置下可能不可靠

現代專案建議使用 Symfony EventDispatcher、Laravel Events 或 PSR-14 相容庫,功能更完善且效能更優。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved