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 和 XML: 使用expat函数(二)
Oct 09 PHP
drupal 代码实现URL重写
May 04 PHP
php购物车实现代码
Oct 10 PHP
PHP 第二节 数据类型之转换
Apr 28 PHP
深入理解PHP之数组(遍历顺序)  Laruence原创
Jun 13 PHP
PHP递归返回值时出现的问题解决办法
Feb 19 PHP
php防注入,表单提交值转义的实现详解
Jun 10 PHP
php inc文件使用的风险和注意事项
Nov 12 PHP
CI框架常用经典操作类总结(路由,伪静态,分页,session,验证码等)
Nov 21 PHP
ThinkPHP 3使用OSS的方法
Jul 19 PHP
laravel 之 Eloquent 模型修改器和序列化示例
Oct 17 PHP
php框架CI(codeigniter)自动加载与自主创建对象操作实例分析
Jun 06 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实现投票功能的方法
2015/09/28 PHP
PHP下使用mysqli的函数连接mysql出现warning: mysqli::real_connect(): (hy000/1040): ...
2016/02/14 PHP
PHP 搜索查询功能实现
2016/11/29 PHP
使用PHP连接数据库_实现用户数据的增删改查的整体操作示例
2017/09/01 PHP
thinkphp5 URL和路由的功能详解与实例
2017/12/26 PHP
PHP数据对象映射模式实例分析
2019/03/29 PHP
ThinkPHP5与单元测试PHPUnit使用详解
2020/02/23 PHP
PHP7 错误处理机制修改
2021/03/09 PHP
js 实现复制到粘贴板的功能代码
2010/05/13 Javascript
javascript学习笔记(七)利用javascript来创建和存储cookie
2011/04/08 Javascript
基于jQuery实现复选框的全选 全不选 反选功能
2014/11/24 Javascript
jQuery实现视频作为全屏幕背景
2014/12/18 Javascript
jQuery结合ajax实现动态加载文本内容
2015/05/19 Javascript
javascript高级选择器querySelector和querySelectorAll全面解析
2016/04/07 Javascript
聊一聊JS中this的指向问题
2016/06/17 Javascript
AngularJS控制器之间的数据共享及通信详解
2016/08/01 Javascript
Vue2实现组件props双向绑定
2016/12/02 Javascript
vue + webpack如何绕过QQ音乐接口对host的验证详解
2018/07/01 Javascript
详解Vue项目在其他电脑npm run dev运行报错的解决方法
2018/10/29 Javascript
vue组件定义,全局、局部组件,配合模板及动态组件功能示例
2019/03/19 Javascript
Vue中computed和watch有哪些区别
2020/12/19 Vue.js
python实现JAVA源代码从ANSI到UTF-8的批量转换方法
2015/08/10 Python
Python爬虫使用脚本登录Github并查看信息
2018/07/16 Python
对python 操作solr索引数据的实例详解
2018/12/07 Python
Django中如何使用sass的方法步骤
2019/07/09 Python
python实现的读取网页并分词功能示例
2019/10/29 Python
Python Sphinx使用实例及问题解决
2020/01/17 Python
tensorflow模型继续训练 fineturn实例
2020/01/21 Python
移动端HTML5开发神器之vconsole详解
2020/12/15 HTML / CSS
安全资金保障制度
2014/01/23 职场文书
关于青春的演讲稿500字
2014/08/22 职场文书
公司财务会计主管应聘求职信
2014/09/26 职场文书
教师节主持词开场白
2015/05/29 职场文书
改进工作作风心得体会
2016/01/23 职场文书
学校趣味运动会开幕词
2016/03/04 职场文书
SpringCloud超详细讲解Feign声明式服务调用
2022/06/21 Java/Android