基于PHP SPL的观察者模式
本帖最后由 m-chris 于 2019-7-22 10:36 编辑PS:第一次发帖还有点小激动,如有哪里写的不对的,还请指教.
观察者模式是一种对象行为模式。它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
这其实可以用于在一个对象发生变化时,其他依赖它的对象都得到通知并自动更新.
下面上代码,LOGIN类是被观察者,实现了SplSubject接口,这个接口用于验证登录是否正确,如果正确,则LOGIN_SUCCESS, 如果用户名密码错误,则LOGIN_WRONG,其他错误LOGIN_UNKNOWN.
文件名Login.php
include './LoginObserver.php';
session_start();
class Login implements SplSubject{
private $storage;
private $username = 'chris';
private $password = '123456';
public $status ;
const LOGIN_SUCCESS = 1;
const LOGIN_WRONG = 2;
const LOGIN_UNKNOWN = 3;
function __construct()
{
$this->storage = new SplObjectStorage();
if(!isset($_SESSION['login_wrongnum'])){
$_SESSION['login_wrongnum'] = 0;
}
}
function attach(SplObserver $observer){
$this->storage->attach($observer);
}
function detach(SplObserver $observer)
{
$this->storage->detach($observer);
}
function notify(){
foreach($this->storage as $obs){
$obs->update($this);
}
}
function loginhandle(){
//增加观察者
$this->attach(new EmailObserver);
$this->attach(new WriteObserver);
$ip = '127.0.0.1';
$username = isset($_GET['username']) ? $_GET['username'] : '';
$password = isset($_GET['password']) ? $_GET['password'] : '';
if($username!= $this->username || $password!=$this->password){
$this->setStatus(self::LOGIN_WRONG,$ip);
$_SESSION['login_wrongnum'] = $_SESSION['login_wrongnum']+1;
$check = false;
}else{
$this->setStatus(self::LOGIN_SUCCESS,$ip);
$check = true;
}
$this->notify();
return $check;
}
public function setStatus($status,$ip){
$this->status = $status;
$this->ip = $ip;
}
public function getStatus(){
return $this->status;
}
}
$login = new Login;
#下面是两个观察者,邮件观察者和写观察者,其中邮件观察者是当输入错误3次以上将以发送邮件并禁用该用户,而写观察者只要用户名密码不正确就会输出,这里只是伪代码以echo进行展示,具体逻辑请各位看管自己补充完整文件名:LoginObserver.php
<?php
class EmailObserver implements SplObserver{
public function update(SplSubject $subject)
{
if($_SESSION['login_wrongnum']>2 ){
echo "登录错误超过3次,账户已禁用并已经给管理员发送邮件!\n";
}
}
}
class WriteObserver implements SplObserver{
public function update(SplSubject $subject){
if($subject->status == 1 && $_SESSION['login_wrongnum']<2){
echo "登录成功!";
}else if($subject->status == 1 && $_SESSION['login_wrongnum']>2){
echo "记录日志:虽然用户名密码正确,但是已经连续输入几次错误\n";
}else{
echo "记录日志:连续输入多次错误密码";
}
}
}
页:
[1]