PHP使用观察者模式处理异常信息的方法详解


Posted in PHP onSeptember 24, 2019

本文实例讲述了PHP使用观察者模式处理异常信息的方法。分享给大家供大家参考,具体如下:

异常信息的捕获对编程测试有着重要的意义,这里结合观察者模式,探索如何处理异常信息。

关于观察者模式,如果还没有接触过的话,博客园有很多优秀的博友做了详细的 解释。笔者觉得,所谓观察者模式,必须有两个重要组成部分:一个主题对象,多个观察者。在使用的时候,我们可以将观察者像插头一样插到主题对象这个插座上,利用主题对象完成相应功能。

既然观察者要作为插头,必须要有一个统一的口径才能插到相同的插座上,因而先定义一个接口,Exception_Observer.php:

<?php
/**
 * 定义的规范
 */
interface Exception_Observer{
  public function update(Observer_Exception $e);
}
?>

相对于众多观察者,我们首先应该关注唯一的主题对象,Observer_Exception.php:

<?php
class Observer_exception extends Exception{
  public static $_observers=array();
  public static function attach(Exception_Observer $observer){
    self::$_observers[]=$observer;
  }
  public function __construct($message=null,$code=0){
    parent::__construct($message,$code);
    $this->notify();
  }
  public function notify(){
    foreach (self::$_observers as $observer) {
      $observer->update($this);
    }
  }
}

我们可以清楚地看到,静态变量$_observers用来放置插入的观察者,notify()用来通知所有观察者对象。

这里需要注意 $observer->update($this); 里面 $this 的用法,很多初学者会感到“原来 $this 也可以这么用啊”。

一个小问题: $_observers 不是静态变量可不可以? 这个问题我们后面回答。

定义两个观察者,原则上实现接口所定义的功能。

Email_Exception_Observer.php:

class Emailing_Exception_Observer implements Exception_Observer{
  protected $_email="huanggbxjp@sohu.com";
  function __construct($email=null)
  {
    if ($email!==null&&filter_var($email,FILTER_VALIDATE_EMAIL)) {
      $this->_email=$email;
    }
  }
  public function update(Observer_Exception $e){
    $message="时间".date("Y-m-d H:i:s").PHP_EOL;
    $message.="信息".$e->getMessage().PHP_EOL;
    $message.="追踪信息".$e->getTraceAsString().PHP_EOL;
    $message.="文件".$e->getFile().PHP_EOL;
    $message.="行号".$e->getLine().PHP_EOL;
    error_log($message,1,$this->_email);
  }
}

Logging_Exception_Observer.php:

<?php
class Logging_Exception_Observer implements Exception_Observer
{
  protected $_filename="F:/logException.log";
  function __construct($filename=null)
  {
    if ($filename!==null&&is_string($filename)) {
      $thvis->_filename=$filename;
    }
  }
  public function update(Observer_Exception $e){
    $message="时间".date("Y-m-d H:i:s").PHP_EOL;
    $message.="信息".$e->getMessage().PHP_EOL;
    $message.="追踪信息".$e->getTraceAsString().PHP_EOL;
    $message.="文件".$e->getFile().PHP_EOL;
    $message.="行号".$e->getLine().PHP_EOL;
    error_log($message,3,$this->_filename);
  }
}

设计完所有该有的主体对象和插件,我们做个小小的测试:

<?php
require 'Exception_Observer.php';
require 'Observer_Exception.php';
require 'Logging_Exception_Observer.php';
require 'Emailing_Exception_Observer.php';
Observer_Exception::attach(new Logging_Exception_Observer());
class MyException extends Observer_Exception{
  public function test(){
    echo 'this is a test';
  }
  public function test1(){
    echo "我是自定义的方法处理这个异常";
  }
}
try {
  throw new MyException("出现异常,记录一下");
} catch (MyException $e) {
  echo $e->getMessage();
  echo "<ht/>";
}
?>

本实例首先先加载观察者,其后进行其他操作。回到上面提出的问题, $_observers 可以不是静态变量吗?答案是不可以。如果 $_observers 不是静态变量,加载观察者的行为对后续操作没有影响。static让所有实例成员共享某个变量。即便类继承也同样有效。有兴趣的可以继续探索下static的神奇作用吧。

本例显示输出与一般情况无异,但不同的是已在自定义的文件下生成了相应的日志。虽然最后实现的功能再简单不过,很多人甚至可以用更少的代码更简单的方法实现,但是,在实现更加复杂系统的情况下,观察者模式给我们带来很大方便。

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
作为PHP程序员应该了解MongoDB的五件事
Jun 03 PHP
改写ThinkPHP的U方法使其路由下分页正常
Jul 02 PHP
PHP操作MySQL事务实例
Nov 05 PHP
PHP获取当前完整URL地址的函数
Dec 21 PHP
php curl 获取https请求的2种方法
Apr 27 PHP
php实现zip文件解压操作
Nov 03 PHP
抛弃 PHP 代价太高
Apr 26 PHP
Yii视图操作之自定义分页实现方法
Jul 14 PHP
PHP实现简易blog的制作
Oct 24 PHP
phpMyAdmin无法登陆的解决方法
Apr 27 PHP
php使用str_replace替换多维数组的实现方法分析
Jun 15 PHP
HTTP头隐藏PHP版本号实现过程解析
Dec 09 PHP
php连接sftp的作用以及实例代码
Sep 23 #PHP
php依赖注入知识点详解
Sep 23 #PHP
php引用和拷贝的区别知识点总结
Sep 23 #PHP
php异常处理捕获错误整理
Sep 23 #PHP
ThinkPHP 5.x远程命令执行漏洞复现
Sep 23 #PHP
PHP开启目录引索+fancyindex漂亮目录浏览带搜索功能
Sep 23 #PHP
redis+php实现微博(三)微博列表功能详解
Sep 23 #PHP
You might like
后宫无数却洁身自好的男主,唐三只爱小舞
2020/03/02 国漫
php结合飞信 免费天气预报短信
2009/05/07 PHP
php求两个目录的相对路径示例(php获取相对路径)
2014/03/27 PHP
php+ajax实现带进度条的上传图片功能【附demo源码下载】
2016/09/14 PHP
PHP设计模式(八)装饰器模式Decorator实例详解【结构型】
2020/05/02 PHP
JScript的条件编译
2007/05/29 Javascript
理解Javascript_08_函数对象
2010/10/15 Javascript
Javascript开发之三数组对象实例介绍
2012/11/12 Javascript
基于jQuery实现下拉收缩(展开与折叠)特效
2012/12/25 Javascript
THREE.JS入门教程(5)你应当知道的十件事
2013/01/24 Javascript
详解JavaScript中undefined与null的区别
2014/03/29 Javascript
初识Node.js
2014/09/03 Javascript
javascript中Function类型详解
2015/04/28 Javascript
Google 地图API资料整理及详细介绍
2016/08/06 Javascript
AngularJs  Creating Services详解及示例代码
2016/09/02 Javascript
JS代码实现百度地图 画圆 删除标注
2016/10/12 Javascript
JavaScript实现的商品抢购倒计时功能示例
2017/04/17 Javascript
vue2.x集成百度UEditor富文本编辑器的方法
2018/09/21 Javascript
详解React之key的使用和实践
2018/09/29 Javascript
Angular Material Icon使用详解
2018/11/07 Javascript
jQuery - AJAX load() 实例用法详解
2019/08/27 jQuery
vue+elementUI组件table实现前端分页功能
2020/11/15 Javascript
[02:26]DOTA2英雄米拉娜基础教程
2013/11/25 DOTA
Django框架的使用教程路由请求响应的方法
2018/07/03 Python
Python实用技巧之利用元组代替字典并为元组元素命名
2018/07/11 Python
python如何读取bin文件并下发串口
2019/07/05 Python
使用Django xadmin 实现修改时间选择器为不可输入状态
2020/03/30 Python
简单了解如何封装自己的Python包
2020/07/08 Python
写好自荐信的技巧
2013/11/08 职场文书
党员批评与自我批评
2014/02/12 职场文书
《与象共舞》教学反思
2014/02/24 职场文书
亮化工程实施方案
2014/03/17 职场文书
企业务虚会发言材料
2014/10/20 职场文书
vue项目打包后路由错误的解决方法
2022/04/13 Vue.js
解决vue自定义组件@click点击失效问题
2022/04/30 Vue.js
Android Studio实现简易进制转换计算器
2022/05/20 Java/Android