异常处理(又称为错误处理)功能提供了处理程序运行时出现的错误或异常情况的方法。

  异常处理通常是防止未知错误产生所采取的处理措施。异常处理的好处是你不用再绞尽脑汁去考虑各种错误,这为处理某一类错误提供了一个很有效的方法,使编程效率大大提高。当异常被触发时,通常会发生:
          当前代码状态被保存
         代码执行被切换到预定义的异常处理器函数
          根据情况,处理器也许会从保存的代码状态重新开始执行代码,终止脚本执行,或从代码中另外的位置继续执行脚本

PHP 5 提供了一种新的面向对象的错误处理方法。可以使用检测(try)、抛出(throw)和捕获(catch)异常。即使用try检测有没有抛出(throw)异常,若有异常抛出(throw),使用catch捕获异常。

一个 try 至少要有一个与之对应的 catch。定义多个 catch 可以捕获不同的对象。PHP 会按这些 catch 被定义的顺序执行,直到完成最后一个为止。而在这些 catch 内,又可以抛出新的异常。

1. 异常的使用

当一个异常被抛出时,其后的代码将不会继续执行,PHP 会尝试查找匹配的 "catch" 代码块。如果一个异常没有被捕获,而且又没用使用set_exception_handler() 作相应的处理的话,那么 PHP 将会产生一个严重的错误,并且输出未能捕获异常(Uncaught Exception ... )的提示信息。

抛出异常,但不去捕获它:

上面的代码会获得类似这样的一个致命错误:

  1. Fatal error: Uncaught exception 'Exception' with message 'Always throw this error' in E:\sngrep\index.php on line 5
  2. Exception: Always throw this error in E:\sngrep\index.php on line 5
  3. Call Stack:
  4. 0.0005 330680 1. {main}() E:\sngrep\index.php:0 

2. Try, throw 和 catch

要避免上面这个致命错误,可以使用try catch捕获掉。

处理处理程序应当包括:
         Try - 使用异常的函数应该位于 "try" 代码块内。如果没有触发异常,则代码将照常继续执行。但是如果异常被触发,会抛出一个异常。
       Throw - 这里规定如何触发异常。每一个 "throw" 必须对应至少一个 "catch"
       Catch - "catch" 代码块会捕获异常,并创建一个包含异常信息的对象

抛出异常并捕获掉,可以继续执行后面的代码:

在 "try" 代码块检测有有没有抛出“throw”异常,这里抛出了异常。
    "catch" 代码块接收到该异常,并创建一个包含异常信息的对象 ($e)。
    通过从这个 exception 对象调用 $e->getMessage(),输出来自该异常的错误消息
    为了遵循“每个 throw 必须对应一个 catch”的原则,可以设置一个顶层的异常处理器来处理漏掉的错误。

3. 扩展 PHP 内置的异常处理类

用户可以用自定义的异常处理类来扩展 PHP 内置的异常处理类。以下的代码说明了在内置的异常处理类中,哪些属性和方法在子类中是可访问和可继承的。(注:以下这段代码只为说明内置异常处理类的结构,它并不是一段有实际意义的可用代码。)

  1. <?php
  2. class Exception
  3. {
  4. protected $message = 'Unknown exception'; // 异常信息
  5. protected $code = 0; // 用户自定义异常代码
  6. protected $file; // 发生异常的文件名
  7. protected $line; // 发生异常的代码行号
  8.  
  9. function __construct($message = null, $code = 0);
  10.  
  11. final function getMessage(); // 返回异常信息
  12. final function getCode(); // 返回异常代码
  13. final function getFile(); // 返回发生异常的文件名
  14. final function getLine(); // 返回发生异常的代码行号
  15. final function getTrace(); // backtrace() 数组
  16. final function getTraceAsString(); // 已格成化成字符串的 getTrace() 信息
  17.  
  18. /* 可重载的方法 */
  19. function __toString(); // 可输出的字符串
  20. }

如果使用自定义的类来扩展内置异常处理类,并且要重新定义构造函数的话,建议同时调用parent::__construct() 来检查所有的变量是否已被赋值。当对象要输出字符串的时候,可以重载__toString() 并自定义输出的样式。

构建自定义异常处理类:

  1. <?php
  2.  
  3. /**
  4. *
  5. * 自定义一个异常处理类
  6. */
  7.  
  8. class MyException extends Exception
  9. {
  10. // 重定义构造器使 message 变为必须被指定的属性
  11. public function __construct($message, $code = 0) {
  12. // 自定义的代码
  13.  
  14. // 确保所有变量都被正确赋值
  15. parent::__construct($message, $code);
  16. }
  17.  
  18. // 自定义字符串输出的样式 */
  19. public function __toString() {
  20. return __CLASS__ . ": [{$this->code}]: {$this->message}\n";
  21. }
  22.  
  23. public function customFunction() {
  24. echo "A Custom function for this type of exception\n";
  25. }
  26. }
  27. // 例子 1:抛出自定义异常,但没有默认的异常
  28. echo ' 例子 1', '<br>';
  29. try {
  30. // 抛出自定义异常
  31. throw new MyException('1 is an invalid parameter', 5);
  32. } catch (MyException $e) { // 捕获异常
  33. echo "Caught my exception\n", $e;
  34. $e->customFunction();
  35. } catch (Exception $e) { // 被忽略
  36. echo "Caught Default Exception\n", $e;
  37. }
  38. // 执行后续代码
  39. // 例子 2: 抛出默认的异常 但没有自定义异常
  40. echo '<br>', ' 例子 2:', '<br>';
  41. try {
  42. // 抛出默认的异常
  43. throw new Exception('2 isnt allowed as a parameter', 6);
  44. } catch (MyException $e) { // 不能匹配异常的种类,被忽略
  45. echo "Caught my exception\n", $e;
  46. $e->customFunction();
  47. } catch (Exception $e) {// 捕获异常
  48. echo "Caught Default Exception\n", $e;
  49. }
  50. // 执行后续代码
  51. // 例子 3: 抛出自定义异常 ,使用默认异常类对象来捕获
  52. echo '<br>', ' 例子 3:', '<br>';
  53. try {
  54. // 抛出自定义异常
  55. throw new MyException('3 isnt allowed as a parameter', 6);
  56. } catch (Exception $e) { // 捕获异常
  57. echo "Default Exception caught\n", $e;
  58. }
  59.  
  60. // 执行后续代码
  61. // 例子 4
  62. echo '<br>', ' 例子 4:', '<br>';
  63. try {
  64. echo 'No Exception ';
  65. } catch (Exception $e) { // 没有异常,被忽略
  66. echo "Default Exception caught\n", $e;
  67. }
  68.  
  69. // 执行后续代码

MyException 类是作为旧的 exception 类的一个扩展来创建的。这样它就继承了旧类的所有属性和方法,我们可以使用 exception 类的方法,比如 getLine() 、 getFile() 以及 getMessage()。

4. 嵌套异常处理

如果在内层 "try" 代码块中异常没有被捕获,则它将在外层级上查找 catch 代码块去捕获。

5. 设置顶层异常处理器 (Top Level Exception Handler)

set_exception_handler() 函数可设置处理所有未捕获异常的用户定义函数。

  1. <?php
  2. function myException($exception)
  3. {
  4. echo "<b>Exception:</b> " , $exception->getMessage();
  5. }
  6.  
  7. set_exception_handler('myException');
  8. throw new Exception('Uncaught Exception occurred');

输出结果:Exception: Uncaught Exception occurred

6. 异常的规则

  • 需要进行异常处理的代码应该放入 try 代码块内,以便捕获潜在的异常。
  • 每个 try 或 throw 代码块必须至少拥有一个对应的 catch 代码块。
  • 使用多个 catch 代码块可以捕获不同种类的异常。
  • 可以在 try 代码块内的 catch 代码块中再次抛出(re-thrown)异常。

简而言之:如果抛出了异常,就必须捕获它,否则程序终止执行。

PHP错误异常处理详解【转载】的更多相关文章

  1. malloc 与 free函数详解<转载>

    malloc和free函数详解   本文介绍malloc和free函数的内容. 在C中,对内存的管理是相当重要.下面开始介绍这两个函数: 一.malloc()和free()的基本概念以及基本用法: 1 ...

  2. Spring Boot异常处理详解

    在Spring MVC异常处理详解中,介绍了Spring MVC的异常处理体系,本文将讲解在此基础上Spring Boot为我们做了哪些工作.下图列出了Spring Boot中跟MVC异常处理相关的类 ...

  3. PHP异常处理详解

      PHP异常处理详解 异常处理(又称为错误处理)功能提供了处理程序运行时出现的错误或异常情况的方法. 异常处理通常是防止未知错误产生所采取的处理措施.异常处理的好处是你不用再绞尽脑汁去考虑各种错误, ...

  4. 如约而至,Java 10 正式发布! Spring+SpringMVC+MyBatis+easyUI整合进阶篇(十四)Redis缓存正确的使用姿势 努力的孩子运气不会太差,跌宕的人生定当更加精彩 优先队列详解(转载)

    如约而至,Java 10 正式发布!   3 月 20 日,Oracle 宣布 Java 10 正式发布. 官方已提供下载:http://www.oracle.com/technetwork/java ...

  5. Linux下的I/O复用与epoll详解(转载)

    Linux下的I/O复用与epoll详解 转载自:https://www.cnblogs.com/lojunren/p/3856290.html  前言 I/O多路复用有很多种实现.在linux上,2 ...

  6. jQuery的deferred对象详解(转载)

    本文转载自: jQuery的deferred对象详解(转载)

  7. Java 反射 设计模式 动态代理机制详解 [ 转载 ]

    Java 反射 设计模式 动态代理机制详解 [ 转载 ] @author 亦山 原文链接:http://blog.csdn.net/luanlouis/article/details/24589193 ...

  8. GridView内容详解(转载)

    GridView内容详解(转载) GridView是ASP.NET界面开发中的一个重要的控件,对GridView使用的熟练程度直接影响软件开发的进度及功能的实现.(车延禄)GridView的主要新特性 ...

  9. http500:服务器内部错误案例详解(服务器代码语法错误或者逻辑错误)

    http500:服务器内部错误案例详解(服务器代码语法错误或者逻辑错误) 一.总结 服务器内部错误可能是服务器中代码运行的时候的语法错误或者逻辑错误 二.http500:服务器内部错误案例详解 只是一 ...

随机推荐

  1. mybatis---知识点复习

    mybatis的配置文件是configuation.xml是配置文件,主要是配置jdbc(用来创建sessionfactory)以及映射文件的别名, 一对多: <mapper namespace ...

  2. 微信小程序官方demo学习

    最近微信小程序很火,很喜欢那种轻应用,用完就走的理念.于是,下载好微信开发者工具,学习一下官方demo. 体验下来,有类似react和vue的感觉,dom类似react那种组件的,data-bindi ...

  3. mac下搭建cordova开发环境

    Apache Cordova 原名叫PhoneGap.是一个用基于HTML,CSS和JavaScript的,创建移动跨平台移动应用程序的快速开发平台.PhoneGap最初由Nitobi开发,2011年 ...

  4. 【定位:PDF文件定位关键字所在坐标和页码】

    iText简介: iText是著名的开放源码的站点sourceforge一个项目,是用于生成PDF文档的一个java类库.通过iText不仅可以生成PDF或rtf的文档,而且可以将XML.Html文件 ...

  5. 《JS权威指南学习总结--8.8 函数式编程和8.8.1使用函数处理数组》

    内容要点:    和Lisp.Haskell不同,JS并非函数式编程语言,但在JS中可以像操控对象一样操控函数,   也就是说可以在JS中应用函数式编程技术.ES5中的数组方法(诸如map()和red ...

  6. hdu_5879_Cure(打表)

    题目链接:hdu_5879_Cure 题意: 给你一个n,让你计算1/k2的和,k从1到n. 题解: 因为只保留5位小数,所以打个100W的表,比这个数大的直接输出最后一位就行了 #include&l ...

  7. Unity开发Oculus游戏

    1.下载Oculus对应自己操作系统的SKD&RunTime 下载地址 我这里是window系统,下载的是0.6.0.0版本的 2.安装RunTime,电脑右下角状态栏会出现一个小眼睛表示安装 ...

  8. struts入门学习(二)

    一  struts的各种视图的转发与重定向 1 struts跳转到指定的JSP页面,只需要修改配置文件 <package name="user" namespace=&quo ...

  9. LeetCode OJ 42. Trapping Rain Water

    Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...

  10. Java 容器一些知识

    一.Collection 1.static 方法: Collections.sort(List<T>):实现List排序功能 Collections.fill(List<T> ...