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缓存技术介绍
Nov 25 PHP
PHP中的日期处理方法集锦
Jan 02 PHP
php 处理上百万条的数据库如何提高处理查询速度
Feb 08 PHP
利用PHP函数计算中英文字符串长度的方法
Nov 11 PHP
php中call_user_func函数使用注意事项
Nov 21 PHP
php取得字符串首字母的方法
Mar 25 PHP
PHP常用字符串操作函数实例总结(trim、nl2br、addcslashes、uudecode、md5等)
Jan 09 PHP
php similar_text()函数的定义和用法
May 12 PHP
php用户密码加密算法分析【Discuz加密算法】
Oct 12 PHP
Yii框架防止sql注入,xss攻击与csrf攻击的方法
Oct 18 PHP
php curl发送请求实例方法
Aug 01 PHP
Laravel服务容器绑定的几种方法总结
Jun 14 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对二维数组进行排序的简单实例
2013/12/19 PHP
PHP+memcache实现消息队列案例分享
2014/05/21 PHP
比较简单的异步加载JS文件的代码
2009/07/18 Javascript
jQuery UI Datepicker length为空或不是对象错误的解决方法
2010/12/19 Javascript
JS判断表单输入是否为空(示例代码)
2013/12/23 Javascript
JavaScript转换二进制编码为ASCII码的方法
2015/04/16 Javascript
javascript字符串与数组转换汇总
2015/05/26 Javascript
JS实现可直接显示网页代码运行效果的HTML代码预览功能实例
2015/08/06 Javascript
JS+CSS实现仿msn风格选项卡效果代码
2015/10/22 Javascript
如何使用PHP+jQuery+MySQL实现异步加载ECharts地图数据(附源码下载)
2016/02/23 Javascript
JavaScript判断数组是否存在key的简单实例
2016/08/03 Javascript
jQuery对checkbox 复选框的全选全不选反选的操作
2016/08/09 Javascript
JavaScript数据结构之单链表和循环链表
2017/11/28 Javascript
JS中精巧的自动柯里化实现方法
2017/12/12 Javascript
vue的toast弹窗组件实例详解
2018/05/14 Javascript
详解vue组件开发脚手架
2018/06/15 Javascript
javascript 原型与原型链的理解及实例分析
2019/11/23 Javascript
jQuery实现可编辑的表格
2019/12/11 jQuery
vue从零实现一个消息通知组件的方法详解
2020/03/16 Javascript
[06:44]2014DOTA2国际邀请赛-钥匙体育馆开战 开幕式振奋人心
2014/07/19 DOTA
[02:08]什么藏在DOTA2 TI9“小紫本”里?斧王历险记告诉你!
2019/05/17 DOTA
python将人民币转换大写的脚本代码
2013/02/10 Python
pycharm设置注释颜色的方法
2018/05/23 Python
python爬虫实例详解
2018/06/19 Python
python3使用SMTP发送HTML格式邮件
2018/06/19 Python
Python OpenCV处理图像之图像直方图和反向投影
2018/07/10 Python
Python批处理更改文件名os.rename的方法
2018/10/26 Python
django与小程序实现登录验证功能的示例代码
2019/02/19 Python
HTML5中FileReader接口使用方法实例详解
2017/08/26 HTML / CSS
使用canvas绘制超炫时钟
2014/12/17 HTML / CSS
歌唱比赛策划方案
2014/06/06 职场文书
2014年内部审计工作总结
2014/12/09 职场文书
2015年度企业工作总结
2015/05/21 职场文书
关于做家务的心得体会
2016/01/23 职场文书
Python办公自动化之教你如何用Python将任意文件转为PDF格式
2021/06/28 Python
光之国的四大叛徒:第一贝利亚导致宇宙毁灭,赛文奥特曼在榜
2022/03/18 日漫