// 实现功能:登录时 通知安全模块 和 广告模块
// 预定义接口: SplObserver观察者 与 SplSubject被观察者
class User implements SplSubject
{
protected $login_num;
protected $hobby;
protected $_subject;
public function __construct($login_num, $hobby)
{
$this->login_num = $login_num;
$this->hobby = $hobby;
// 存储观察者对象
$this->_subject = new SplObjectStorage();
}
public function __get($name)
{
// TODO: Implement __get() method.
return $this->$name;
}
public function login()
{
// 操作...
$this->notify();
}
// SplSubject 接口
public function attach(SplObserver $observer)
{
// TODO: Implement attach() method.
$this->_subject->attach($observer);
}
public function detach(SplObserver $observer)
{
// TODO: Implement detach() method.
$this->_subject->detach($observer);
}
public function notify()
{
// TODO: Implement notify() method.
foreach ($this->_subject as $observer) {
$observer->update($this);
}
}
}
// 观察者 再此观察用户登录
// 安全检查
class safe implements SplObserver
{
public function update(SplSubject $subject)
{
// TODO: Implement update() method.
if ($subject->login_num > 10) {
echo '今日登陆次数超过10次,可能存在密码泄露问题,请重置密码!';
} else {
echo '今日第' . $subject->login_num . '次安全登录!';
}
}
}
// 广告推广
class ad implements SplObserver
{
public function update(SplSubject $subject)
{
// TODO: Implement update() method.
if ($subject->hobby == 'sports') {
echo '这是体育广告!';
} else {
echo '随机广告!';
}
}
}
$hobby = ['sports', 'eat', 'drink', 'sleep', 'play'];
$user = new User(random_int(1, 20), $hobby[shuffle($hobby)]);
$user->attach(new safe());
$user->attach(new ad());
// 用户登录时触发一些列观察者
$user->login();