文章教程

16.2PHP中的异常处理类及其用法

9/17/2020 9:31:19 PM 人评论 次浏览

16.2 PHP中的异常处理类及其用法

PHP5增加了类似于其他语言的异常处理模块。这使得在PHP程序中排查错误、捕获异常更加简单容易,也使得PHP程序在健壮性方面有很大改善和提高。这一模块在PHP中的具体体现就是,PHP提供了一个名叫Exception的类完成对PHP程序异常的处理,这个类包含了一些处理异常的函数,这些函数可以捕获程序异常和错误。本节将介绍PHP中的该异常处理类及类函数用法。

16.2.1 PHP中的异常处理类

PHP5提供了内置的异常处理类——Exception,首先介绍该类的以下成员函数。

·getMessage():可以返回对错误描述信息。

·getCode():返回错误代码,以数字形式出现。

·getFile():返回发生错误的文件名。

·getLine():返回发生错误的代码行号。

·getTrace():返回backtrace()数组。

·getTraceAsString():返回已格式化成字符串的、由函数getTrace()所产生的信息。

·__toString():产生异常的字符串信息,它可以重载。注意,该函数最前部是两个下划线。

代码16-1是该内置异常处理类的完整代码,从这个类的定义可以看出哪些属性和方法(成员函数)在用户派生的子类中是可以访问和继承的。

代码16-1 PHP5内置异常处理类的完整代码16-1.php


     01 <?php
     02 class Exception
     03 {
     04     protected $message = 'Unknown exception';     //
异常信息
     05     protected $code = 0;                          //
用户自定义异常代码
     06     protected $file;                              //
发生异常的文件名
     07     protected $line;                              //
发生异常的代码行号
     08 
     09     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     function __toString();                        //
可输出的字符串
     19 }
     20 ?>

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

16.2.2 PHP程序中捕获异常的方法

如下所示为两种抛出异常的格式。

·try…catch…:该处理异常方式的具体格式如下。


     try
     {
         //
这里是可能出现异常或错误的代码,比如文件操作、数据库操作等
     }
     catch(Exception $e)
     {
         //
输出错误信息
     }

·throw:关键字throw用来抛出一个异常。

需要进行异常处理的代码都必须放入try代码块内,以便捕获可能存在的异常。每一个try至少要有一个与之对应的catch。使用多个catch可以捕获不同的类所产生的异常。当try代码块不再抛出异常或者找不到catch能匹配所抛出的异常时,PHP代码就会在跳转到最后一个catch的后面继续执行。

在PHP代码中所产生的异常可被throw语句抛出并被catch语句捕获。当然,PHP允许在catch代码块内再次抛出(throw)异常。当一个异常被抛出时,其后的代码将不会继续执行,而PHP就会尝试继续查找第一个能与之匹配的catch。如果一个异常没有被捕获,而且又没用使用set_exception_handler()作相应的处理的话,那么PHP将会产生一个严重的错误,并且输出UncaughtException...(未捕获异常)的提示信息。

代码16-2是try...catch和throw一起用的示例代码,从这个代码可以看出try…catch和throw在程序中是如何工作的。

代码16-2 使用try…catch捕获并处理异常的示例程序16-2.php


     01 <?php
     02 try
     03 {
     04     $error = '
抛出异常信息,并且跳出try
块<br/>';
     05     if(is_dir('./test'))
     06     {
     07         echo '
检测到../ch16
是一个目录';
     08         echo '<br/>';
     09         echo '
可能继续做其他一些操作';
     10         echo '<br/>';
     11         echo '....';
     12         echo '<br/>';
     13     }
     14     else
     15     {
     16         throw new Exception($error,12345);              //
抛出异常
     17     }
     18     echo '
上面throw
异常的话,这行代码不会执行,转而执行catch
块<br/>';
     19 }
     20 catch(Exception $e)                                     //
获取异常
     21 {
     22     echo '
捕获异常: ' . $e->getMessage() . "<br/>
错误代码:" . $e->getCode().'<br/>';                                                                                                                  
    //
显示$error
和
     23 12345
     24     echo '<br/>';
     25 }
     26 
     27 echo '
继续执行';
     ?>

图16-1 使用try…catch捕获程序异常

【代码解析】这段代码在try块中试着判断当前目录下是否存在名叫test的目录,如果不存在这个目录,那么就会执行第16行语句,通过关键字throw抛出异常。这个异常是一个Exception类的对象,通过new运算符生成,并且用错误信息$error和错误代码12345初始化该对象,以便后面catch该异常时(代码第20行),可以获取这些信息。一旦抛出异常,那么try块中剩下的代码就不再执行,程序流程转至相应的catch块执行。代码16-2的执行结果如图16-1所示。

这段代码中自定义了错误信息和错误代码,通过关键字throw抛出一个异常Exception类的对象$e,最终通过该对象调用其成员函数输出错误信息和代码。

16.2.3 获取异常信息

当一个程序遇到一个错误时,可以建立Exception类的对象来处理,类似于如下代码。


$e = new Exception("Could not open file");

此时,Excetpion类的构造函数将通过一错误信息创建一个该类的对象$e。建立这个对象后,通常使用关键字throw将这个异常(或者说错误)抛出。throw将脚本的执行中止,并使相关的Exception对象对客户代码可用。

Exception类的成员函数getMessage()用来产生一个对错误信息的描述。代码16-3演示了该成员函数的用法。

代码16-3 Exception类的成员函数getMessage()的使用16-3.php


     01 <?php
     02 $file = './test/readme.txt';                    //
指定文件地址
     03 
     04 try
     05 {
     06     if(is_dir($file))                           //
判断是不是目录
     07     {
     08         echo '
检测到目录';
     09     }
     10     else
     11     {
     12         //
创建异常对象,错误信息将有Exception
类的成员函数getMessage()
返回
     13         throw new Exception('
未找到该目录或文件');
     14     }
     15 }
     16 catch(Exception $e)
     17 {
     18     echo '
捕获异常: ' . $e->getMessage();
     19     echo '<br/>===============================';
     20     echo '<br/>';
     21 }
     22 
     23 echo '
程序执行完毕';
     24 ?>

图16-2 使用Exception 类的成员函数getMessage()

【代码解析】这段代码将判断文件是否为目录的代码放在try块中,并且当所判断的文件不是目录时,创建异常类Exception的对象,并使用“未找到该目录或文件”这段信息初始化该对象,如代码第13行所示。这段信息被赋值给Exception类的成员变量$message,这个成员变量可以由Exception类的成员函数getMessage()返回,如这段代码第18行,通过Exception类的对象$e调用函数getMessage()将这个异常信息输出。这段程序的执行结果如图16-2所示。

这里只是举一个简单例子说明如何使用Exception类,以及使用该类的成员函数getMessage()获取异常信息。一般是通过该类派生出处理某种操作的异常处理子类,来完成对异常的处理。在派生类中实现throw出异常,然后在使用这个类的程序中try…catch。这样做的好处是,可以在子类中提供更多更完善有效的自定义功能,还可以区分不同类型的异常。

16.2.4 获取错误发生的文件

有了通过Exception类获取错误信息的程序,获取发生错误的文件名就很简单了。只需在程序中使用Exception类的成员函数getFile()即可,如代码16-4所示。

代码16-4 使用Exception类的成员函数获取发生错误的文件名16-4.php


     01 <?php
     02 $file = './test/readme.txt';                    //
指定文件地址
     03 
     04 try
     05 {
     06     if(is_dir($file))                           //
判断是不是目录
     07     {
     08         echo '
检测到目录';
     09     }
     10     else
     11     {
     12         //
创建异常对象,错误信息将有Exception
类的成员函数getMessage()
返回
     13         throw new Exception('
未找到该目录或文件');
     14     }
     15 }
     16 catch(Exception $e)
     17 {
     18     echo '
捕获异常: ' . $e->getMessage();
     19     echo '<br/><br/>';
     20     echo '
错误所在文件:'. $e->getFile();
     21     echo '<br/>===============================';
     22     echo '<br/>';
     23 }
     24 
     25 echo '
程序执行完毕';
     26 ?>

【代码解析】这段程序仅仅是在代码16-3的基础上添加了对Exception类的成员函数getFile()的调用,如代码第20行所示,执行结果如图16-3所示。

16.2.5 获取错误发生的行

类似获取错误文件名称的办法,在程序中通过调用Exception类的成员函数getLine(),可以获取错误所在的行号,如代码16-5所示。

代码16-5 使用Exception类的成员函数getLine()获取发生错误的所在行16-5.php


     01 <?php
     02 $file = './test/readme.txt';                    //
指定文件地址
     03 
     04 try
     05 {
     06     if(is_dir($file))                           //
判断是否是目录
     07     {
     08         echo '
检测到目录';
     09     }
     10     else
     11     {
     12         //
创建异常对象,错误信息将有Exception
类的成员函数getMessage()
返回
     13         throw new Exception('
未找到该目录或文件');
     14     }
     15 }
     16 catch(Exception $e)
     17 {
     18     echo '
捕获异常: ' . $e->getMessage();
     19     echo '<br/><br/>';
     20     echo '
错误所在文件:'. $e->getFile();
     21     echo '<br/><br/>';
     22     echo '
错误所在行号:'. $e->getLine();
     23     echo '<br/>===============================';
     24     echo '<br/>';
     25 }
     26 
     27 echo '
程序执行完毕';
     28 ?>

【代码解析】这段代码在第22行调用Exception类的成员函数getLine()获取异常发生所在的行号,其执行结果如图16-4所示。

图16-3 使用Exception类的成员函数getFile()

图16-4 使用Exception类的成员函数getLine()

教程类别