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 获取目录下的图片并随机显示的代码
Dec 28 PHP
php5 apache 2.2 webservice 创建与配置(java)
Jan 27 PHP
php切割页面div内容的实现代码分享
Jul 31 PHP
浅析Apache中RewriteCond规则参数的详细介绍
Jun 30 PHP
php过滤XSS攻击的函数
Nov 12 PHP
php内存缓存实现方法
Jan 24 PHP
php获取、检查类名、函数名、方法名的函数方法
Jun 25 PHP
Yii使用migrate命令执行sql语句的方法
Mar 15 PHP
centos+php+coreseek+sphinx+mysql之一coreseek安装篇
Oct 25 PHP
php获取指定数量随机字符串的方法
Feb 06 PHP
总结PHP代码规范、流程规范、git规范
Jun 18 PHP
PHP数组常用函数实例小结
Aug 20 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 Ajax中文乱码问题解决方法
2009/02/27 PHP
php 404错误页面实现代码
2009/06/22 PHP
Thinkphp模板标签if和eq的区别和比较实例分析
2015/07/01 PHP
PHP实现cookie跨域session共享的方法分析
2019/08/23 PHP
始终在屏幕中间显示Div的代码(css+js)
2011/03/10 Javascript
js 可拖动列表实现代码
2011/12/13 Javascript
JQuery加载图片自适应固定大小的DIV
2013/09/12 Javascript
jQuery移除tr无效的解决方法(tr是动态添加)
2014/09/22 Javascript
jquery获取checkbox的值并post提交
2015/01/14 Javascript
深入解读JavaScript中的Iterator和for-of循环
2015/07/28 Javascript
JavaScript实现的圆形浮动标签云效果实例
2015/08/06 Javascript
jQuery form插件之ajaxForm()和ajaxSubmit()的可选参数项对象
2016/01/23 Javascript
浅谈Angular中ngModel的$render
2016/10/24 Javascript
详解Vue如何支持JSX语法
2017/11/10 Javascript
最实用的JS数组函数整理
2017/12/05 Javascript
微信小程序保存图片到相册权限设置
2020/04/09 Javascript
详解vue 中 scoped 样式作用域的规则
2020/09/14 Javascript
使用Python脚本将绝对url替换为相对url的教程
2015/04/24 Python
Python 使用os.remove删除文件夹时报错的解决方法
2017/01/13 Python
NLTK 3.2.4 环境搭建教程
2018/09/19 Python
对Python 多线程统计所有csv文件的行数方法详解
2019/02/12 Python
简单介绍一下pyinstaller打包以及安全性的实现
2020/06/02 Python
python实现npy格式文件转换为txt文件操作
2020/07/01 Python
深入浅析pycharm中 Make available to all projects的含义
2020/09/15 Python
Python Charles抓包配置实现流程图解
2020/09/29 Python
HTML5的postMessage的使用手册
2018/12/19 HTML / CSS
阿根廷首家户外用品制造商和经销商:Montagne
2018/02/12 全球购物
综合实践活动方案
2014/02/14 职场文书
学生安全教育材料
2014/02/14 职场文书
电子工程求职信
2014/07/17 职场文书
三好生演讲稿
2014/09/12 职场文书
工作收入证明模板
2014/10/10 职场文书
党员教师群众路线个人整改措施
2014/10/28 职场文书
2014年党支部工作总结
2014/11/13 职场文书
个人先进事迹材料
2014/12/29 职场文书
Python基本数据类型之字符串str
2021/07/21 Python