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 相关文章推荐
phpMyAdmin2.11.6安装配置方法
Aug 24 PHP
php操作JSON格式数据的实现代码
Dec 24 PHP
php缓冲 output_buffering和ob_start使用介绍
Jan 30 PHP
ThinkPHP之getField详解
Jun 20 PHP
PHP mysql事务问题实例分析
Jan 18 PHP
php单例模式的简单实现方法
Jun 10 PHP
PHP中session跨子域的三种实现方法
Jul 25 PHP
学习PHP Cookie处理函数
Aug 09 PHP
老生常谈PHP位运算的用途
Mar 12 PHP
PHP读取、解析eml文件及生成网页的方法示例
Sep 04 PHP
PHP多进程简单实例小结
Nov 09 PHP
php post换行的方法
Feb 03 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
PHP文件与目录操作示例
2016/12/24 PHP
PHP中的浅复制与深复制的实例详解
2017/10/26 PHP
Tab页界面,用jQuery及Ajax技术实现
2009/09/21 Javascript
jquery的$getjson调用并获取远程的JSON字符串问题
2012/12/10 Javascript
Node.js的特点和应用场景介绍
2014/11/04 Javascript
jquery插件validation实现验证身份证号等
2015/06/04 Javascript
JS运动相关知识点小结(附弹性运动示例)
2016/01/08 Javascript
基于Angularjs实现分页功能
2016/05/30 Javascript
微信 java 实现js-sdk 图片上传下载完整流程
2016/10/21 Javascript
jQuery基于xml格式数据实现模糊查询及分页功能的方法
2016/12/25 Javascript
ES6新特性七:数组的扩充详解
2017/04/21 Javascript
如何理解Vue的render函数的具体用法
2017/08/30 Javascript
浅析node应用的timing-attack安全漏洞
2018/02/28 Javascript
jQuery实现侧边栏隐藏与显示的方法详解
2018/12/22 jQuery
详释JavaScript执行环境与执行栈
2019/04/02 Javascript
小程序如何构建骨架屏
2019/05/29 Javascript
使用Webpack 搭建 Vue3 开发环境过程详解
2020/07/28 Javascript
全面解析js中的原型,原型对象,原型链
2021/01/25 Javascript
[05:59]2018DOTA2国际邀请赛寻真——只为胜利的Secret
2018/08/13 DOTA
python里将list中元素依次向前移动一位
2014/09/12 Python
Python实现的批量下载RFC文档
2015/03/10 Python
python中json格式数据输出的简单实现方法
2016/10/31 Python
详解Python之unittest单元测试代码
2018/01/24 Python
Python实现压缩文件夹与解压缩zip文件的方法
2018/09/01 Python
python将字符串转变成dict格式的实现
2019/11/18 Python
python函数定义和调用过程详解
2020/02/09 Python
在keras中model.fit_generator()和model.fit()的区别说明
2020/06/17 Python
中间件分为哪几类
2016/09/18 面试题
夜大自我鉴定
2013/10/31 职场文书
运动会致辞稿50字
2014/02/04 职场文书
2014年“四风”问题个人整改措施
2014/09/17 职场文书
2014县政府领导班子三严三实对照检查材料思想汇报
2014/09/26 职场文书
2014年助理工程师工作总结
2014/11/14 职场文书
小学生纪律委员竞选稿
2015/11/19 职场文书
IDEA 链接Mysql数据库并执行查询操作的完整代码
2021/05/20 MySQL
Windows10安装Apache2.4的方法步骤
2022/06/25 Servers