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 iconv 函数转gb2312的bug解决方法
Oct 11 PHP
PHP与MySQL开发的8个技巧小结
Dec 17 PHP
PHPExcel读取Excel文件的实现代码
Dec 06 PHP
session在php5.3中的变化 session_is_registered() is deprecated in
Nov 12 PHP
PHP集成百度Ueditor 1.4.3
Nov 23 PHP
php+mysql实现无限分类实例详解
Jan 15 PHP
深入浅析PHP7.0新特征(五大新特征)
Oct 29 PHP
在Mac OS上搭建PHP的Yii框架及相关测试环境
Feb 14 PHP
Yii2框架dropDownList下拉菜单用法实例分析
Jul 18 PHP
分享一个漂亮的php验证码类
Sep 29 PHP
magento后台无法登录解决办法的两种方法
Dec 09 PHP
Yii框架where查询用法实例分析
Oct 22 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 var_dump()函数的详解
2013/06/05 PHP
php的hash算法介绍
2014/02/13 PHP
PHP Header失效的原因分析及解决方法
2016/11/16 PHP
JS 页面自动加载函数(兼容多浏览器)
2009/05/18 Javascript
Javascript 中的类和闭包
2010/01/08 Javascript
Javascript中的包装类型介绍
2015/04/02 Javascript
JavaScript如何动态创建table表格
2020/08/02 Javascript
JS实现的表格行鼠标点击高亮效果代码
2015/11/27 Javascript
js 获取范围内的随机数实例代码
2016/08/02 Javascript
JS基于正则截取替换特定字符之间字符串操作示例
2017/02/03 Javascript
jQuery实现淡入淡出的模态框
2017/02/09 Javascript
JS使用正则表达式验证身份证号码
2017/06/23 Javascript
ES6深入理解之“let”能替代”var“吗?
2017/06/28 Javascript
基于AngularJS实现表单验证功能
2017/07/28 Javascript
jQuery实现鼠标移到某个对象时弹出显示层功能
2018/08/23 jQuery
JS猜数字游戏实例讲解
2020/06/30 Javascript
基于vue中的scoped坑点解说
2020/09/04 Javascript
通过实例解析jQ Ajax操作相关原理
2020/09/23 Javascript
[01:07:02]DOTA2-DPC中国联赛 正赛 iG vs PSG.LGD BO3 第三场 2月26日
2021/03/11 DOTA
Python中的列表生成式与生成器学习教程
2016/03/13 Python
Python多进程同步简单实现代码
2016/04/27 Python
Python中循环引用(import)失败的解决方法
2018/04/22 Python
解决pip install xxx报错SyntaxError: invalid syntax的问题
2018/11/30 Python
Python Numpy库安装与基本操作示例
2019/01/08 Python
pycharm 批量修改变量名称的方法
2019/08/01 Python
浅析python标准库中的glob
2020/03/13 Python
python list的index()和find()的实现
2020/11/16 Python
大学生物业管理求职信
2013/10/24 职场文书
党校培训自我鉴定范文
2014/04/10 职场文书
统计专业自荐书
2014/07/06 职场文书
酒店七夕情人节活动策划方案
2014/08/24 职场文书
村道德模范事迹材料
2014/08/28 职场文书
餐饮服务员岗位职责
2015/02/09 职场文书
中学生综合素质自我评价
2015/03/06 职场文书
2016春节慰问信范文
2015/03/25 职场文书
入党积极分子半年考察意见
2015/06/02 职场文书