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

文件 ① 定义观察者的接口

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. OC内存管理(ARC)

    1.什么是ARC Automatic Reference Counting,自动引用计数,即ARC,可以说是WWDC2011和iOS5所引入 的最大的变革和最激动人心的变化.ARC是新的LLVM 3. ...

  2. Android仿微信界面

    效果图 原理介绍 1.先绘制一个颜色(例如:粉红) 2.设置Mode=DST_IN 3.绘制我们这个可爱的小机器人 回答我,显示什么,是不是显示交集,交集是什么?交集是我们的小机器人的非透明区域,也就 ...

  3. Material Design入门

    本文主要包括以下内容 ToolBar的使用 RecyclerView的定义与使用 ToolBar 风格 (style) 界面 (layout) 程序 (java) 首先自定义一个theme,并将App ...

  4. Ubuntu 下搭建SVN服务器

    root@iZ25q0jd99eZ:~# sudo apt-get install subversion root@iZ25q0jd99eZ:/etc/subversion# mkdir /svn r ...

  5. ytu 2030: 求实数绝对值(水题)

    2030: 求实数绝对值 Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 10  Solved: 10[Submit][Status][Web Board] ...

  6. 烟大 Contest1025 - 《挑战编程》第二章:数据结构 Problem A: Jolly Jumpers(水题)

    Problem A: Jolly Jumpers Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 10  Solved: 4[Submit][Status] ...

  7. android 拨号

    public class CallActivity extends Activity { @Override public void onCreate(Bundle savedInstanceStat ...

  8. hdu 4622 **

    题意:Suppose there are the symbols M, I, and U which can be combined to produce strings of symbols cal ...

  9. Java判断文件编码格式

    转自:http://blog.csdn.net/zhangzh332/article/details/6719025 一般情况下我们遇到的文件编码格式为GBK或者UTF-8.由于中文Windows默认 ...

  10. Distinct和Group by去除重复字段记录

    重复记录 有两个意义,一是完全重复的记录,也即所有字段均重复的记录 二是部分关键字段重复的记录,比如Name字段重复,而其他字段不一定重复或都重复可以忽略. 1.对于第一种重复,比较容易解决,使用 s ...