使异常处理变得更灵活、可观察,可以使用设计模式中的观察者模式。

文件 ① 定义观察者的接口

ExceptionObserver.php:

 <?php
/*
给观察者定义的规范
*/
interface ExceptionObserver{
public function update(Observer_Exception $e);
}

文件 ② 观察者模式的自定义异常类 Observer_Exception

Observer_Exception.php:

 <?php
class Observer_Exception extends Exception{
//保存观察者信息,静态属性
public static $_observer = array();
//添加观察者,静态方法
public static function attach(ExceptionObserver $observer){
//添加成员
self::$_observer[] = $observer;
} //重载父类的构造函数
public function __construct($message = null, $code = 0){
parent::__construct($message, $code);
$this->notify();
} //通知每一个观察者的方法
public function notify(){
foreach(self::$_observer as $observer){
$observer->update($this);
}
}
}

文件 ③ 观察者1.把异常信息记录到文件中

Log_Exception_Observer.php:

 <?php
//观察者1.把异常记录到日志文件中
class Log_Exception_Observer implements ExceptionObserver{
protected $_filename = 'D:/practise/php/Error/LogException.log';
public function __construct($filename = null){
if($filename != null && is_string($filename)){
$this->_filename = $filename;
}
} public function update(Observer_Exception $e){
$message = '时间:'.date('Y-m-d H:i:s', time()).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);
}
}

文件 ④ 观察者5.把异常信息通过邮件形式发送给管理员

Email_Exception_Observer.php:

 <?php
//观察者2.把异常记录通过邮件形式发送
class Email_Exception_Observer implements ExceptionObserver{
protected $_email = '472323087@qq.com';
public 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', time()).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);
}
}

文件⑤ 测试文件

testObersver.php:

 <?php
header('content-type:text/html; charset=utf-8'); require 'ExceptionObserver.php'; //接口
require 'Observer_Exception.php'; //观察者模式的自定义异常类
require 'Log_Exception_Observer.php'; //观察者1
require 'Email_Exception_Observer.php'; //观察者2 //添加观察者,把异常信息记录在文件中
Observer_Exception::attach(new Log_Exception_Observer());//不传参数则保存到默认的文件中 //自定义异常类
class MyException extends Observer_Exception{
public function test(){
echo '测试1:自定义方法处理异常';
}
} //测试
try{
throw new MyException('出现异常,记录');
}catch(MyException $e){
echo $e->getMessage();
echo '<hr>';
$e->test();
}

运行 testObersver.php,输出:

同时文件 LogException.log:

PHP 错误与异常 笔记与总结(15 )使用观察者模式处理异常信息的更多相关文章

  1. PHP 错误与异常 笔记与总结(10)错误处理器测试

    关联文件:myErrorHandler.php (上一篇) 先测试通知级别的错误的自定义处理: testErrorHandler.php <?php require_once 'myErrorH ...

  2. C++ primer plus读书笔记——第15章 友元、异常和其他

    第15章 友元.异常和其他 1. 友元类的所有方法都可以访问原有类的私有成员和保护成员.另外,也可以做更严格的限制,只将特定的成员函数指定为另一个类的友元.哪些函数.成员函数.或类为友元是由类定义的, ...

  3. PHP 错误与异常 笔记与总结(16 )自定义异常处理器

    可以使用自定义异常处理器来处理所有未捕获的异常(没有用 try/catch 捕获的异常). set_exception_handler():设置一个用户定义的异常处理函数,当一个未捕获的异常发生时所调 ...

  4. 《C++ Primer Plus》第15章 友元、异常和其他 学习笔记

    友元使得能够为类开发更灵活的接口.类可以将其他函数.其他类和其他类的成员函数作为友元.在某些情况下,可能需要前向声明,需要特别注意类和方法声明的顺序,以正确地组合友元.潜逃类是在其他类中生命的类,它有 ...

  5. 0040 Java学习笔记-多线程-线程run()方法中的异常

    run()与异常 不管是Threade还是Runnable的run()方法都没有定义抛出异常,也就是说一条线程内部发生的checked异常,必须也只能在内部用try-catch处理掉,不能往外抛,因为 ...

  6. java异常笔记

    1:<java核心技术卷一>473页提到:如果在子类中覆盖了超类的一个方法,子类方法中声明的已检查异常不能超过超类方法中声明的异常范围. 显然,如果子类中抛出的异常范围比超类还大.多态将无 ...

  7. 编写高质量代码改善C#程序的157个建议[用抛异常替代返回错误、不要在不恰当的场合下引发异常、重新引发异常时使用inner Exception]

    前言 自从.NET出现后,关于CLR异常机制的讨论就几乎从未停止过.迄今为止,CLR异常机制让人关注最多的一点就是“效率”问题.其实,这里存在认识上的误区,因为正常控制流程下的代码运行并不会出现问题, ...

  8. php错误以及常用笔记

    //语法错误(syntax error)在语法分析阶段,源代码并未被执行,故不会有任何输出. /* [命名规则] */ 常量名 类常量建议全大写,单词间用下划线分隔 // MIN_WIDTH 变量名建 ...

  9. java 检查抛出的异常是否是要捕获的检查性异常或运行时异常或错误

    /** * Return whether the given throwable is a checked exception: * that is, neither a RuntimeExcepti ...

  10. 读书笔记 effective c++ Item 8 不要让异常(exceptions)离开析构函数

    1.为什么c++不喜欢析构函数抛出异常 C++并没有禁止析构函数出现异常,但是它肯定不鼓励这么做.这是有原因的,考虑下面的代码: class Widget { public: ... ~Widget( ...

随机推荐

  1. [转]Java Thread Dump 性能分析

    Java and Thread 一个 web 服务器使用几十到几百个线程来处理大量并发用户,如果一个或多个线程使用相同的资源,线程之间的竞争就不可避免了,并且有时候可能会发生死锁. Thread co ...

  2. sdut 2165:Crack Mathmen(第二届山东省省赛原题,数论)

    Crack Mathmen Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述  Since mathmen take securit ...

  3. win8 鼠标失灵解决办法

    前几天 也没更新,却不知道突然win8 pro 失灵了,是不是ms 后台运行的也不确定,不过更新之后就可以用了. 经供参考: 更新前: 更新后: 我的主板是华硕的,有时候需要重启几次鼠标才显示出来

  4. cocos2dx游戏开发——微信打飞机学习笔记(四)——GameScene的搭建

    一.创建文件 首先呢,就是那个创建新的.h 和 .cpp 的文件,然后可以起名为GameScene 最重要的就是一定要创建在Classes的目录下哦= =,别手抖= =. 二.GameScene.h和 ...

  5. C#学习笔记(二)——变量和表达式

    Ps:使用这两个关键字可以很方便的把头文件收起来(虽然VS已经集成这个功能= =) 但是可以一下子收起来很多个函数 一.变量 1.简单类型 (1)变量类型 (2)示例一 static void Mai ...

  6. 安装完最小化 RHEL/CentOS 7 后需要做的 30 件事情(四)码农网

    17. 安装 Webmin Webmin 是基于 Web 的 Linux 配置工具.它像一个中央系统,用于配置各种系统设置,比如用户.磁盘分配.服务以及 HTTP 服务器.Apache.MySQL 等 ...

  7. css 层叠样式表

    css选择器 派生选择器 根据其元素在其上下文关系来定义样式 <style type="text/css">body{ font-size:12px; color:re ...

  8. [leetCode][012] Two Sum (1)

    [题目]: Given an array of integers, find two numbers such that they add up to a specific target number ...

  9. TYVJ P1038/P1039 忠诚 标签:线段树

    做题记录:2016-08-12 16:30:14 //P1038 描述 老管家是一个聪明能干的人.他为财主工作了整整10年,财主为了让自已账目更加清楚.要求管家每天记k次账,由于管家聪明能干,因而管家 ...

  10. TYVJ P1091 等差数列 Label:dp

    背景 广东汕头聿怀初中 Train#3 Problem 3 描述 等差数列的定义是一个数列S,它满足了(S[i]-S[i-1]) = d (i>1).显然的一个单独的数字或者两个数字也可以形成一 ...