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 相关文章推荐
了解Joomla 这款来自国外的php网站管理系统
Mar 11 PHP
php 文件上传后缀名与文件类型对照表(几乎涵盖所有文件)
May 16 PHP
php 无法加载mysql的module的时候的配置的解决方案引发的思考
Jan 27 PHP
PHP面向对象——访问修饰符介绍
Nov 08 PHP
PHP 基于Yii框架中使用smarty模板的方法详解
Jun 13 PHP
thinkphp模板用法和内容输出实例
Nov 28 PHP
php抓取网站图片并保存的实现方法
Oct 29 PHP
php+mysql实现的二级联动菜单效果详解
May 10 PHP
php rmdir使用递归函数删除非空目录实例详解
Oct 20 PHP
php数据库操作model类(使用__call方法)
Nov 16 PHP
php获取网站根目录物理路径的几种方法(推荐)
Mar 04 PHP
PHP7 新增功能
Mar 09 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测试程序运行时间的类
2012/02/05 PHP
PHP编程风格规范分享
2014/01/15 PHP
smarty内置函数config_load用法实例
2015/01/22 PHP
PHP多进程编程之僵尸进程问题的理解
2017/10/15 PHP
JQuery弹出层示例可自定义
2014/05/19 Javascript
老司机带你解读jQuery插件开发流程
2016/05/16 Javascript
jQuery+json实现动态创建复杂表格table的方法
2016/10/25 Javascript
详解vue.js组件化开发实践
2016/12/14 Javascript
bootstrap实现图片自动轮播
2016/12/21 Javascript
nodejs利用http模块实现银行卡所属银行查询和骚扰电话验证示例
2016/12/30 NodeJs
走进AngularJs之过滤器(filter)详解
2017/02/17 Javascript
微信小程序实现点击返回顶层的方法
2017/07/12 Javascript
微信小程序的生命周期的详解
2017/10/19 Javascript
详解Angular如何正确的操作DOM
2018/07/06 Javascript
koa2+vue实现登陆及登录状态判断
2019/08/15 Javascript
js前端如何写一个精确的倒计时代码
2019/10/25 Javascript
JavaScript实现移动端弹窗后禁止滚动
2020/05/25 Javascript
[00:49]完美世界DOTA2联赛10月28日开团时刻:随便打
2020/10/29 DOTA
Python与shell的3种交互方式介绍
2015/04/11 Python
利用python GDAL库读写geotiff格式的遥感影像方法
2018/11/29 Python
利用Python正则表达式过滤敏感词的方法
2019/01/21 Python
Pytorch加载部分预训练模型的参数实例
2019/08/18 Python
django xadmin中form_layout添加字段显示方式
2020/03/30 Python
PyCharm Ctrl+Shift+F 失灵的简单有效解决操作
2021/01/15 Python
英国骑行、跑步、游泳、铁人三项运动装备专卖店:Wiggle
2016/08/23 全球购物
会计实习期自我鉴定
2013/10/06 职场文书
实习自荐信
2013/10/13 职场文书
安全生产先进个人材料
2014/02/06 职场文书
英文演讲稿
2014/05/15 职场文书
教师党员学习群众路线心得体会
2014/11/04 职场文书
校长师德表现自我评价
2015/03/04 职场文书
财务出纳岗位职责
2015/03/31 职场文书
工厂门卫岗位职责
2015/04/13 职场文书
催款函怎么写
2015/06/24 职场文书
关于nginx 实现jira反向代理的问题
2021/09/25 Servers
教你使用RustDesk 搭建一个自己的远程桌面中继服务器
2022/08/14 Servers