异常机制
一.异常基本知识
1.定义:异常处理用于在指定的错误(异常)情况发生时改变脚本的正常流程,这过程称为异常.
2.基本用法:
try
{
//可能出现的错误(异常)代码
}
catch(Exception $e)
{
//自己处理:捕捉异常并处理,
//自己不处理:抛出一个异常,即如下:
throw $e;
}
其中,Exception是异常类(php中定义好的一个类,具体参见php参考文档:语音参考->异常处理).它已经封装好很多方法,常用如下:
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(); // 可输出的字符串
3.入门案例
案例1:
<?php try { adduser( "weimin" ); echo "adduser()如果出现异常,这句话就不会出现<br>" ; updateuser( "wly1" ); echo "updateuser()如果出现异常,这句话就不会出现<br>" ; } catch (Exception $e ) { echo "error!" . $e ->getMessage(); //getMessage()为异常中一个函数,可返回异常信息 } function adduser( $username ) { if ( $username == "weimin" ) { } else { throw new Exception( "添加失败" ); //抛出异常,及返回一个异常 } } function updateuser( $username ) { if ( $username == "wly" ) { } else { throw new Exception( "修改失败" ); //抛出异常 } } ?> |
结果:
adduser()如果出现异常,这句话就不会出现
error!修改失败
来自 <http://localhost/exception/exception01.php>
二.异常使用的注意事项
1.异常的基本处理:
(1).当异常被抛出,其后的代码不会继续执行,php尝试查找匹配的catch代码块;见案例1.
(2).如果异常没有被捕获,而且有没有使用set_exception_handler()做相应的处理,那么会发生一个严重的错误(致命错误),并输出"Uncaught Exception"(未捕获异常)的错误消息;
(3).当catch一个异常,可以进行处理或者不进行处理(在catch函数中,直接抛出异常,即 throw $e,这时将启动php系统默认异常处理器(函数)来处理,见案例2。或者自己定义一个顶级异常处理器(函数),见案例3);
通俗理解:即第一次抛出异常后,使用try{},ctach{}捕获到第一次抛出的异常,这时我们如果不对第一次抛出的异常进行处理,可以将此异常进行第二次抛出,这时,此异常将交给php默认异常处理器(函数)进行处理,或者交给用户自己定义的顶级异常处理器(函数)进行处理。
其中,定义顶级异常处理,需要两个步骤:
步骤一:定义顶级异常处理函数;
步骤二:修改默认定义异常处理函数set_exception_handler("函数名");
案例2:
<?php function A1( $val ) { if ( $val == "A" ) { throw new Exception ( "不要输入A" ); //第一次抛出异常 } } function B1( $val ) { if ( $val == "B" ) { throw new Exception ( "不要输入B" ); //第一次抛出异常 } } try { A1( "A" ); } catch (Exception $e ) { throw $e ; //第二次抛出异常 /*捕获异常后,继续抛出异常(第二次抛出异常),这时候将会启动php默认的异常处理器来处理, 也可以自己定义一个顶级异常处理*/ } ?> |
结果:
Fatal error: Uncaught exception 'Exception'with message '不要输入A' inE:\Software_default\wamp_wwwroot\exception\exception02.php:6 Stack trace: #0E:\Software_default\wamp_wwwroot\exception\exception02.php(18): A1('A') #1{main} thrown in E:\Software_default\wamp_wwwroot\exception\exception02.phpon line 6
来自 <http://localhost/exception/exception02.php>
案例3:
<?php function MyException( $e ) //用户定义的顶级异常处理函数 { echo "<b>我是顶级异常处理函数,</b>其中,异常信息为:" . $e ->getMessage(); } set_exception_handler( "MyException" ); //修改默认的顶级异常处理函数 function A1( $val ) { if ( $val == "A" ) throw new Exception ( "不要输入A" ); //抛出异常 } function B1( $val ) { if ( $val == "B" ) throw new Exception ( "不要输入B" ); } try { A1( "A" ); } catch (Exception $e ) { throw $e ; /*继续抛出异常,这时候将会启动php默认的异常处理器来处理, 也可以自己定义一个顶级异常处理*/ } ?> |
结果:
我是顶级异常处理函数,其中,异常信息为:不要输入A
来自 <http://localhost/exception/exception03.php>
(4).如果抛出一个异常,就必须捕获它(否则会报错,产生Fatal error错误),或者使用用户定义的顶级异常处理函数进行处理
2.也可以自己定义一个异常类
class MyException Exception
{
}
3.使用多个catch代码块可以捕获不同种类的异常
(1).基本用法
try
{
//代码
//可能抛出多种异常
}
catch(PDOException $e)//数据库异常
{
//代码
}
catch(Exception $e)
{
//代码
}
(2).案例
案例4:
<?php //定义一个异常类 class MyException1 extends Exception{ } class MyException2 extends Exception{ } function A() { throw new MyException1( "a" ); } function B() { throw new MyException1( "b" ); } function C() { try { A(); //抛出MyException1 B(); //抛出MyException2 } catch (Exception1 $e1 ){ echo $e1 ->getMessage(); } catch (Exception2 $e2 ){ echo $e2 >getMessage(); } } C(); ?> |
结果:
Fatal error: Uncaughtexception 'MyException1' with message 'a' inE:\Software_default\wamp_wwwroot\exception\exception04.php:12 Stack trace: #0E:\Software_default\wamp_wwwroot\exception\exception04.php(21): A() #1E:\Software_default\wamp_wwwroot\exception\exception04.php(31): C() #2 {main}thrown in E:\Software_default\wamp_wwwroot\exception\exception04.phpon line 12
来自 <http://localhost/exception/exception04.php>
由于产生不捕获的异常,php默认显示其异常处理函数,这时,我们添加用户自定义的顶级处理函数
案例5:
<?php //定义一个异常类 class MyException1 extends Exception{ } class MyException2 extends Exception{ } function MyException( $e ) { echo "<b>我是顶级异常处理函数,</b>其中,异常信息为:" . $e ->getMessage(); } set_exception_handler( "MyException" ); //修改默认的顶级异常处理函数 function A() { throw new MyException1( "a" ); } function B() { throw new MyException1( "b" ); } function C() { try { A(); //抛出MyException1 B(); //抛出MyException2 } catch (Exception1 $e1 ){ //Exception1 是异常类名 echo $e1 ->getMessage(); } catch (Exception2 $e2 ){ //Exception2是异常类名 echo $e2 >getMessage(); } } C(); ?> |
结果:
我是顶级异常处理函数,其中,异常信息为:a
来自 <http://localhost/exception/exception05.php>
3.PHP异常抛出的BUG
案例6:
<?php try { $a =8/0; } catch (Exception $e ){ echo $e ->getMessage(); echo "异常" ; } ?> |
结果:
Warning: Division by zero in E:\Software_default\wamp_wwwroot\exception\exception06.phpon line 3
来自 <http://localhost/exception/exception06.php>
在案例6中,8/0,php认为是错误,而不是异常,所以,没有抛出异常,因此捕获不到异常
案例7:
<?php try { $f = fopen ( "aa.txt" , "r" ); //aa.txt在当前路径下并不存在 } catch (Exception $e ){ echo $e ->getMessage(); echo "异常" ; } ?> |
结果:
Warning: fopen(aa.txt) [function.fopen]: failed toopen stream: No such file or directory in E:\Software_default\wamp_wwwroot\exception\exception07.phpon line 3
来自 <http://localhost/exception/exception07.php>
在案例7中, fopen()是一个很老的函数,从php1就已经存在了,当时并没有异常处理机制,php认为是错误,而不是异常,所以,没有抛出异常,因此捕获不到异常
共同学习,写下你的评论
评论加载中...
作者其他优质文章