在实际工作中,怎样可以去有效的控制多条可能出现错误或是异常的代码?针对这个问题,我们需要用到PHP异常处理机制!
代码结构如下:
try{
//可能出现错误或是异常的代码
//抛出异常
throw new Exception("异常内容");
}
//catch 捕获
//Exception 异常类(是PHP定义好的一个类)
catch(Exception $e){
//对异常处理
//1、自己处理
//2、自己不处理,将其抛出
}
结构比较简单,下面举一个例子:
try{
//调用下面两个自定义函数,发现抛出异常,则执行下面catch中的代码
addUser("xiaoming");
updateUser("xiaomi");
}catch(Exception $e){
//接收错误信息
var_dump($e);
echo "错误信息:".$e->getMessage();
echo "错误文件:".$e->getFile();
}
function addUser($username){
if($username == "xiaoming"){
//添加OK(没有结果就是最好的结果-类似Linux)
}else{
//抛出异常
throw new Exception("添加失败");
}
}
function updateUser($username){
if($username == "xiaomi"){
//修改OK
}else{
//抛出异常
throw new Exception("修改失败");
}
}
注意事项:
1、当异常被抛出时,其后的代码不会继续执行,当捕获到一个异常后,try块里的后续代码不继续执行
2、如果有一个异常发生了,但是没有catch捕获,则会输出一个UncatchedException的致命错误消息
3、当catch捕获到一个异常后,可以处理也可以不处理(留空),也可以选择继续把异常抛出
上文注意事项第2、3条提到的情况,可根据下面代码详细理解:
function a1($val){
if($val > 100){
throw new Exception("输入过大");
}
}
function a2($val){
if($val == 'hello'){
throw new Exception("不要输入hello");
}
}
try{
a2("hello");
}catch(Exception $e){
//获取异常信息
echo $e->getMessage();
//如果不处理,可以继续抛出,这时将会启动PHP默认的异常处理器来处理(页面中报错,和没有捕获异常相同的错误提示信息,上文注意事项第2条提到的错误)
throw $e;
//解决方法:可以自己定义一个顶级异常处理器.
}
//定义一个顶级异常处理器
function my_exception($e){
echo "我是顶级异常处理器";
echo "
";
echo "错误信息:".$e->getMessage();
}
//如果选择抛给默认的异常处理器来处理,需要设置用户定义的异常处理函数来处理
set_exception_handler("my_exception");//设置需要写在文件开头
还有一种情况,用户自定义异常处理类,继承系统内置异常处理类
我们可以根据上面的图片看到,PHP异常处理机制实际上是,系统内置了一个Exception异常处理类,我们所调用的各种异常提示信息,都已事先在这个类中定义好
举例说明:
//自定义异常处理类MyEcxeptionA
class MyExceptionA extends Exception{
//1、这个类中不可以写构造函数,不存在构造函数继承
//2、可以自定义其它方法,捕获到错误后可以调用该方法
}
//自定义异常处理类MyExceptionB
class MyExceptionB extends Exception{
}
function A(){
throw new MyExceptionA("我是自定义异常类A");
}
function B(){
throw new MyExceptionB("我是自定义异常类B");
}
try{
A(); //抛出MyExceptionA
B(); //抛出MyExceptionB
}catch(MyExceptionA $e1){
//输出A异常的信息
$e1->getMessage();
}catch(MyExceptionB $e2){
//输出B异常的信息
$e2->getMessage();
}
上面代码的注意事项:
自定义的错误处理类,继承了系统内置异常处理类,一定不能再写构造方法,即使继承了系统内置类的构造方法也可以。
还有一个问题
try{
$i=8/0;
}catch(Exception $e){
echo "ok";
echo $e->getMessage();
}
上面这段代码不会输出“ok”,原因是8/0错误,并没有抛出异常。
又例如:
try{
$fp=fopen("a.txt","r");
}catch(Exception $e){
echo "ok";
echo $e->getMessage();
}
上面代码中如果a.txt不存在,也会报错,不会输出“ok”,原因是没有异常抛出
说明:fopen是php中比较古老的函数,没有OOP思想,并不会抛出异常。且由于函数比较古老的原因(php最原始版本就存在),暂时没有办法解决。
所以可看出,能不能catch到异常,要取决于,有没有真的异常抛出来
PHP异常处理机制讲完,欢迎进行补充,有疑问请留言。