错误处理之函数返回值OR异常处理
2016-05-06 11:04
447 查看
问题:
1、错误处理的方法有哪些?
2、使用函数返回值还是抛出异常?
3、PHP 原框架下的异常处理机制是怎样的?
4、PHP Yii框架下的错误处理方案是怎样的?有什么参考意义?
使用成员变量保存错误信息:在对象内部预设一个 errors变量(可能更多的时候是一个数组),把内部处理的报错信息暂存起来,最后使用getErrors函数获取错误信息。
抛出异常
触发事件:需要框架支持。
暂时只想到这么多了,盼指正!
函数返回值的特点
1)函数返回值比较直接,可以使用true|flase直接表达处理结果,使用状态代码来表示更多的执行结果(推荐使用http的状态码,易读易懂),使用数据或者对象来携带更多的数据,性能较高。
2)返回值的修改、添加、减少会对依赖方带来改动,如果调用的地方很多,修改起来也很麻烦。添加返回值后还需要调用方添加相应的处理代码,往往表现为一个if语句。
3)嵌套很深时,层层都需要对返回值进行处理,层层都需要显式判断,会带来不少冗余代码,而且经常出现处理漏状态的情况。
异常处理
1)异常处理是面向对象语言的处理方案,把错误信息抽象为固定的对象,携带着对象固有的报错信息、格式等等,具有较高的可读性,可能从异常名字就可以判断报错类型。
2)使用异常来处理报错信息,可以让程序变得更简洁,代码只需要关注主流程,省了很多状态判断。同时开发语言的异常处理机制封装了很详细的报错信息,便于定位问题。
3)对调用方依赖较少,新增的异常也不需要一定要求调用方去处理,调用方只需要关注该处理的异常即可。即使深层嵌套也可以把底层异常有效暴露给顶层。
4)异常处理是一种对象处理,而且try和catch也会对数据的出入栈带来消耗,所以性能稍低,这点不难理解。
5)开发人员需要对各种各样的异常创建类定义,开发成本较高。
综上所述,使用哪种方式来反馈错误,的确是要看场景。个人觉得,操作频率高的代码模块尽量少使用异常处理,但是要确保返回信息的简洁。而一些失败因素无法穷举的场景,如果不会出现性能问题,则考虑使用异常。
抛出异常
捕捉异常
如果异常没有被捕获,而且又没用使用 set_exception_handler() 作相应的处理的话,那么将发生一个严重的错误(致命错误),并且输出 “Uncaught Exception” (未捕获异常)的错误消息。
以上是PHP语言中最基本的异常处理代码,Exception对象是PHP内置的异常类,只是简单得接收异常message,然后展示message。
自定义异常类
一个更成熟的做法是根据自己系统的业务特点来定义异常类,然后处理特定业务场景的异常,实现一种另类的条件选择结构。。如下例子,在找不到对应的商品的时候可以抛出找不到商品异常对象。
设置顶层异常处理器 (Top Level Exception Handler)
可以设置顶层异常处理类来处理所有异常。
上面这段代码只为说明内置异常处理类Exception的结构,并不是一段有实际意义的可用代码,在IDE里查看PHP的源码基本都是这样的结构代码,内部实现是C代码,在src包里面可以找到。如果使用自定义的类作为异常处理类,则必须是扩展内置异常处理类Exception,非Exception类的子类是不能作为异常处理类使用的。如果在扩展内置处理类Exception时重新定义构造函数的话,建议同时调用parent::construct()来检查所有的变量是否已被赋值。当对象要输出字符串的时候,可以重载__toString()并自定义输出的样式。可以在自定义的子类中,直接使用内置异常处理Exception类中的所有成员属性,但不能重新改写从该父类中继承过来的成员方法,因为该类的大多数公有方法都是final的。
网上摘录了一段样例代码,供参考!
UML的类图结构如下:
1、其中从PHP原生异常对象中扩展 ErrorException,用于代表所有虚拟机级别的异常,可能需要重启服务才可以重新提供服务。
2、扩展UnexpectedValueException,用于不可知的异常,也就是模糊无法定位具体原因的异常。
3、扩展BadMethodCallException,用于调用不正确的类、方法、错误参数等。
4、扩展Exception,代表框架内部一些专有的报错信息,例如加载配置文件失败、架构初始化异常等等。
![](https://img-blog.csdn.net/20160613122745742)
![](https://img-blog.csdn.net/20160613122802514)
从Yii框架的异常类的定义来看,PHP语言的内部异常类的确不足够用于所有的场景,而不同名字的异常又充当了 errorCode的角色,无形中也是带框架内部加了不少的if分支。
1、错误处理的方法有哪些?
2、使用函数返回值还是抛出异常?
3、PHP 原框架下的异常处理机制是怎样的?
4、PHP Yii框架下的错误处理方案是怎样的?有什么参考意义?
错误处理的方法有哪些?
函数返回值:既return true|false,数组,对象 等使用成员变量保存错误信息:在对象内部预设一个 errors变量(可能更多的时候是一个数组),把内部处理的报错信息暂存起来,最后使用getErrors函数获取错误信息。
抛出异常
触发事件:需要框架支持。
暂时只想到这么多了,盼指正!
使用函数返回值还是抛出异常
如上所述四种处理方法,成员变量的方式多数使用在处理结果不用立即返回的情况,譬如对多个数据字段进行校验返回校验结果,使用场景比较明确。触发事件就主要依赖于框架来实现,复杂的处理逻辑可以考虑,使用场景也相对明确。而函数返回值和抛出异常则用得比较纠结,在编写代码的时候就时常需要考虑什么时候使用异常处理,什么时候考虑返回值,而且在嵌套较深的时候还会让人好好纠结一番。函数返回值的特点
1)函数返回值比较直接,可以使用true|flase直接表达处理结果,使用状态代码来表示更多的执行结果(推荐使用http的状态码,易读易懂),使用数据或者对象来携带更多的数据,性能较高。
2)返回值的修改、添加、减少会对依赖方带来改动,如果调用的地方很多,修改起来也很麻烦。添加返回值后还需要调用方添加相应的处理代码,往往表现为一个if语句。
3)嵌套很深时,层层都需要对返回值进行处理,层层都需要显式判断,会带来不少冗余代码,而且经常出现处理漏状态的情况。
异常处理
1)异常处理是面向对象语言的处理方案,把错误信息抽象为固定的对象,携带着对象固有的报错信息、格式等等,具有较高的可读性,可能从异常名字就可以判断报错类型。
2)使用异常来处理报错信息,可以让程序变得更简洁,代码只需要关注主流程,省了很多状态判断。同时开发语言的异常处理机制封装了很详细的报错信息,便于定位问题。
3)对调用方依赖较少,新增的异常也不需要一定要求调用方去处理,调用方只需要关注该处理的异常即可。即使深层嵌套也可以把底层异常有效暴露给顶层。
4)异常处理是一种对象处理,而且try和catch也会对数据的出入栈带来消耗,所以性能稍低,这点不难理解。
5)开发人员需要对各种各样的异常创建类定义,开发成本较高。
综上所述,使用哪种方式来反馈错误,的确是要看场景。个人觉得,操作频率高的代码模块尽量少使用异常处理,但是要确保返回信息的简洁。而一些失败因素无法穷举的场景,如果不会出现性能问题,则考虑使用异常。
PHP 原框架下的异常处理机制是怎样的
使用异常的基本思路是抛出异常、捕捉异常、处理异常。如下代码所示,可以在任何你希望的地方,通过throw语句来抛出异常对象。抛出异常
throw new Exception("错误描述,描述清楚错误原因和可能的解决方案...");
捕捉异常
如果异常没有被捕获,而且又没用使用 set_exception_handler() 作相应的处理的话,那么将发生一个严重的错误(致命错误),并且输出 “Uncaught Exception” (未捕获异常)的错误消息。
try { //If the exception is thrown, this text will not be shown } catch(Exception $e) { echo 'Message: ' .$e->getMessage(); }
以上是PHP语言中最基本的异常处理代码,Exception对象是PHP内置的异常类,只是简单得接收异常message,然后展示message。
自定义异常类
一个更成熟的做法是根据自己系统的业务特点来定义异常类,然后处理特定业务场景的异常,实现一种另类的条件选择结构。。如下例子,在找不到对应的商品的时候可以抛出找不到商品异常对象。
class goodsNotFoundException extends Exception { public function errorMessage() { //error message $errorMsg = '找不到 '.$this->getMessage().' 这个商品.'; return $errorMsg; } }
设置顶层异常处理器 (Top Level Exception Handler)
可以设置顶层异常处理类来处理所有异常。
set_exception_handler('allException');
扩展阅读
Exception 的源码阅读:class Exception { protected $message = 'Unknown exception'; //异常信息 private $string; protected $code = 0; //用户自定义异常代码 protected $file; //发生异常的文件名 protected $line; //发生异常的代码行号 private $trace; private $previous; final private function __clone () {} //还不知道什么场景下需要用到 function __construct($message = null, $code = 0){} //构造方法 /* 不可重载的方法 */ final function getMessage(){} //返回异常信息 final function getCode(){} //返回异常代码 final function getFile(){} //返回发生异常的文件名 final function getLine(){} //返回发生异常的代码行号 final function getTrace(){} //backtrace() 数组 final function getTraceAsString(){} //已格成化成字符串的 getTrace() 信息 /* 可重载的方法 */ function __toString(){} //可输出的字符串 }
上面这段代码只为说明内置异常处理类Exception的结构,并不是一段有实际意义的可用代码,在IDE里查看PHP的源码基本都是这样的结构代码,内部实现是C代码,在src包里面可以找到。如果使用自定义的类作为异常处理类,则必须是扩展内置异常处理类Exception,非Exception类的子类是不能作为异常处理类使用的。如果在扩展内置处理类Exception时重新定义构造函数的话,建议同时调用parent::construct()来检查所有的变量是否已被赋值。当对象要输出字符串的时候,可以重载__toString()并自定义输出的样式。可以在自定义的子类中,直接使用内置异常处理Exception类中的所有成员属性,但不能重新改写从该父类中继承过来的成员方法,因为该类的大多数公有方法都是final的。
网上摘录了一段样例代码,供参考!
/* 自定义的一个异常处理类,但必须是扩展内异常处理类的子类 */ class MyException extends Exception{ //重定义构造器使第一个参数 message 变为必须被指定的属性 public function __construct($message, $code=0){ //可以在这里定义一些自己的代码 //建议同时调用 parent::construct()来检查所有的变量是否已被赋值 parent::__construct($message, $code); } public function __toString() { //重写父类方法,自定义字符串输出的样式 return __CLASS__.":[".$this->code."]:".$this->message."<br>"; } public function customFunction() { //为这个异常自定义一个处理方法 echo "按自定义的方法处理出现的这个类型的异常<br>"; } } try { //使用自定义的异常类捕获一个异常,并处理异常 $error = '允许抛出这个错误'; throw new MyException($error); //创建一个自定义的异常类对象,通过throw语句抛出 echo 'Never executed'; //从这里开始,try代码块内的代码将不会再被执行 } catch (MyException $e) { //捕获自定义的异常对象 echo '捕获异常: '.$e; //输出捕获的异常消息 $e->customFunction(); //通过自定义的异常对象中的方法处理异常 } echo '你好呀'; //程序没有崩溃继续向下执行
PHP Yii框架下的错误处理方案是怎样的?有什么参考意义?
yii框架的异常定义集中在vendor\yiisoft\yii2\base目录下,但是限于个人能力,还有部分代码没看懂…UML的类图结构如下:
1、其中从PHP原生异常对象中扩展 ErrorException,用于代表所有虚拟机级别的异常,可能需要重启服务才可以重新提供服务。
2、扩展UnexpectedValueException,用于不可知的异常,也就是模糊无法定位具体原因的异常。
3、扩展BadMethodCallException,用于调用不正确的类、方法、错误参数等。
4、扩展Exception,代表框架内部一些专有的报错信息,例如加载配置文件失败、架构初始化异常等等。
从Yii框架的异常类的定义来看,PHP语言的内部异常类的确不足够用于所有的场景,而不同名字的异常又充当了 errorCode的角色,无形中也是带框架内部加了不少的if分支。
相关文章推荐
- 一个关于if else容易迷惑的问题
- PHP5.2.*防止Hash冲突拒绝服务攻击的Patch
- 深入理解PHP之匿名函数
- JSP/PHP基于Ajax的分页功能实现
- 关于PHP通过PDO用中文条件查询MySQL的问题。
- 什么是设计模式
- PHP数据库长连接mysql_pconnect的细节
- Php Installing An Expansion
- 如何优雅地处理前端异常?
- php7 读取php.ini[4]
- PHP+Apache在Windows 9x下的安装和配置
- IIS 6 的 PHP 最佳配置方法
- 安装Apache和PHP的一些补充
- Linux Apache+MySQL+PHP
- 建立Apache+PHP+MySQL数据库驱动的动态网站
- PHP 5.3.0 安装分析心得
- apache 环境下 php 的配置注意事项
- C#异常处理详解
- 轻松学习C#的异常处理