attach()、detach()、notify()。update(SplSubject $subject)。<?php
// 被觀察者
class Observed implements SplSubject {
protected $_name;
protected $_observers;
public function __construct() {
$this->_observers = new SplObjectStorage();
}
public function attach(SplObserver $observer) {
$this->_observers->attach($observer);
}
public function detach(SplObserver $observer) {
$this->_observers->detach($observer);
}
public function notify() {
foreach ($this->_observers as $observer) {
$observer->update($this);
}
}
// 業務方法:設定名稱並通知
public function setName($name) {
$this->_name = $name;
$this->notify();
}
public function getName() {
return $this->_name;
}
// 另一個業務方法:設定年齡並單獨通知
public function setAge($age) {
$this->age = $age;
foreach ($this->_observers as $observer) {
$observer->showAge($this->_name, $this->age);
}
}
}
// 觀察者
class Observer implements SplObserver {
public function update(SplSubject $subject) {
$this->showMessage($subject);
}
public function showMessage(SplSubject $obj) {
$user = $obj->getName();
if ($user === 'admin') {
echo "您好, $user 歡迎進入管理後台<br/>";
} else {
echo "你好, '$user' 你已被加入用戶列表<br/>";
}
}
public function showAge($name, $age) {
echo "<script>alert('$name 的年齡是: $age')</script>";
}
}
// 使用示範
$subject = new Observed();
$observer = new Observer();
$subject->attach($observer);
$subject->setName('張三'); // 觸發 notify() → update() → showMessage()
$subject->setName('admin'); // 不同歡迎語
$subject->setAge(24); // 直接呼叫觀察者的 showAge()
$subject->attach($observer) 將觀察者存入 SplObjectStorage。setName() → 內部 $this->notify()。notify() 迭代所有觀察者,呼叫 $observer->update($this)。Observer::update() 轉呼叫 showMessage() 完成具體邏輯。attach/detach,支援插件式架構。若需優先級或一次性觀察者,可自行擴充 SplObjectStorage 或改用 SplPriorityQueue 管理觀察者列表。