当前位置:首页>php>PHP设计模式(三) 观察者模式

PHP设计模式(三) 观察者模式

  • 2026-09-05 06:05:34
PHP设计模式(三) 观察者模式

PHP设计模式 三

3 观察者模式

使用场景:一个操作结束后会需要后续操作。

被观察者暴露并抛出对应事件,通过事件分发器触发观察者。

观察者监听事件,对应事件相应并进行操作。

  用户模块    服务      登录处理    事件        登录事件  短信模块    监听      登录  common    interface      事件      事件监听    class      事件分发器

事件interface,要求必须定义事件名和数据。

事件监听interface,要求必须处理对用的事件,检验事件名并执行对应方法。

事件分发器注册监听并在用户模块服务类中调用。

模块下的事件实现事件interface,模块下的监听实现事件监听interface。

执行顺序

controller->logic->注册监听->模块/服务模块/服务->模块/事件->事件分发->模块/监听

假设场景

用户登录,记录上次登录时间ip 本次登录时间ip,发送短信告知。

被观察者为登录操作;观察者为短信发送模块。

common

事件interface

interfaceEvent{publicfunctiongetName(): string;publicfunctiongetData();}

事件监听interface

interfaceListener{publicfunctionhandle(Event $event): void;publicfunctiongetEventName(): string;}

事件分发器

classEventDispatcher{privatearray $listeners = [];//添加监听publicfunctionaddListener(Listener $listener): void{        $eventName = $listener->getEventName();$this->listeners[$eventName][] = $listener;    }//事件分发publicfunctiondispatch(Event $event): void{        $eventName = $event->getName();if (isset($this->listeners[$eventName])) {foreach ($this->listeners[$eventName] as $listener) {                $listener->handle($event);            }        }    }}

基础监听类

可以没有 起到记录日志作用

abstractclassBaseListenerimplementsListener{protectedfunctionlog(string $message): void{echo"[{$this->getEventName()}] " . $message . "\n";    }}

被观察者

用户模块登录事件

classLoginEventimplementsEvent{private string $name = 'user.login';privatearray $data;publicfunction__construct(array $data){$this->data = $data;    }//设置事件名字publicfunctiongetName(): string{return$this->name;    }//获取事件数据publicfunctiongetData(){return$this->data;    }}

用户模块服务

classUserService{private EventDispatcher $dispatcher;publicfunction__construct(){$this->dispatcher = new EventDispatcher();    }//登录操作 publicfunctionlogin(string $phone, string $pwd): void{// to do 登录逻辑 根据$phone和$pwd获取用户信息        $userinfo = [];        $user_id = $userinfo->id;         $login_time = date('Y-m-d H:i:s');        $isSafe = false;if(empty($isSafe)){             $safe_msg ="上次登录时间/IP,本次登录时间/IP";             $userData = ['user_id'=>$userid,'safe_msg'=>$safe_msg,'phone' => $phone,            ];// 触发事件 可改为异步操作$this->dispatcher->dispatch(new LoginEvent($userData));        }return$this->formatLoginInfo($userinfo);    }//格式化登录后信息publicfunctionformatLoginInfo($userinfo){//to do 格式化用户信息      $userinfo_use = [];return $userinfo_use;    }//获取事件分发类publicfunctiongetDispatcher(): EventDispatcher{return$this->dispatcher;    }}

观察者

短信模块 用户登录监听类

classLoginSmsListenerextendsBaseListener{//获取对应事件名字publicfunctiongetEventName(): string{return'user.login';    }//执行对应事件方法publicfunctionhandle(Event $event): void{        $data = $event->getData();$this->log("发送短信到 {$this->phone}");//to do 发送短信//发送$data[safe_msg]到$data[phone];      }}

调用

controller层

classUserextendsController{publicfunctionlogin(){//获取请求参数    $params = (new $Request())->getParams();    $phone = $params['phone'];    $pwd = $params['pwd'];    $userLoginc = new UserLogic();    $result = $userLoginc->login($phone,$pwd);if(1==empty($result[0])){       $returnData =['code'=>200,'msg'=>$result[1],'data'=>$result[2]];    }else{    $returnData =['code'=>$result[0],'msg'=>$result[1],'data'=>[]];    }//返回数据return json_encode($returnData);  }}

logic层

publicfunctionUserLogic{publicfunctionlogin($phone,$pwd){    $userServer = new UserService();try{//注册监听       $dispatcher = $userService->getDispatcher();       $dispatcher->addListener(new LoginSmsListener());//执行登录操作       $userinfo = $userService->logic($phone, $pwd);return [1,"操作成功",$userinfo];      }cache(\Exception $e){return [$e->getCode(),$e->getMessage()];    }  }}

扫描识别二维码关注我们获取更多

最新文章

随机文章