在上一篇文章中,我们提到了编译和语法运行时会出现错误。它们与逻辑无关,不应在程序员编码时出现。也就是说,这些错误要尽量避免到线上环境,不能被try...catch捕获到。例外恰恰相反。什么是例外?异常是指程序运行过程中发生的意想不到的情况。它通常被允许发生并由相应的异常处理程序处理。当然,你也可以选择忽略异常处理,但就像严重错误一样,代码会立即终止执行。异常是业务逻辑中的错误,基本上是人为造成的。我们先通过一段简单的代码来看异常的抛出和捕获:$e);}我们通过throw抛出异常,然后在调用方法时将方法包裹在一个try...catch块中,捕获抛出的异常。这是异常的最基本结构。从这里我们可以看出,异常基本上都是我们手动抛出,让外部处理的。在PHP中,大部分异常都是在类中抛出的,这就是面向对象错误处理的思想。例如PDO类:try{//$pdo=newPDO();//致命错误:未捕获的ArgumentCountError:PDO::__construct()需要至少1个参数,0给定$pdo=newPDO('');}catch(PDOException$e){print_r($e);//invaliddatasourcename}注意上面一行注释的代码,如果没有传参数,就是错误,无法捕获。如果传递的参数错误,则异常。在PDO类的源码中,发现参数不对,抛出。交给上层代码,也就是我们调用者去捕获。接下来我们看看自定义异常类和finally语句块的使用。自定义异常类会继承Exception类,Exception类可以看作是所有异常的基类。其结构如下:classException{protected$message='Unknownexception';//异常消息private$string;//__toString缓存保护$code=0;//用户定义的异常代码protected$file;//发生异常文件名保护$line;//异常发生的行号private$trace;//回溯private$previous;//上一个异常如果嵌套异常publicfunction__construct($message=null,$code=0,Exception$previous=null);最终私有函数__clone();//不可复制,如果克隆异常类会直接产生致命错误finalpublicfunctiongetMessage();//返回异常信息finalpublicfunctiongetCode();//返回异常代码finalpublicfunctiongetFile();//返回异常发生的文件名finalpublicfunctiongetLine();//返回异常发生的代码行号finalpublicfunctiongetTrace();//backtrace()数组最终公共乐趣动作getPrevious();//之前的异常finalpublicfunctiongetTraceAsString();//getTrace()已经格式化为字符串的信息//可重写的公共函数__toString();//outputablestring}通过上面的类定义,我们可以看到我们可以重写构造函数和__toString()方法,还可以使用一些受保护的属性。所以让我们定义一个自定义异常类。类TestException扩展异常{protected$code=200;公共函数__construct($message=null,$code=0,Exception$previous=null){$this->message='TestException:'.$消息;}公共函数__toString(){返回“代码:”。$这个->代码。';'。$this->消息;}}functiontest2(){thrownewTestException('Thisistest2Error...');}try{test2();}catch(TestException$e){echo$e,PHP_EOL;//代码:200;TestException:Thisistest2Error...}还是很容易理解的,大部分PHP框架都会有自定义的Exception组件或者能力提供给我们使用,因为现代框架还是基于面向对象的,所以会定义异常更详细。不同的组件提供不同的异常类来进行异常提示的封装。接下来是finally关键字。其实这也没什么好说的。finally的特点是不管是否有异常都会执行finally关键字定义的代码块里面的内容。try{test2();}catch(TestException$e){echo$e,PHP_EOL;}finally{echo'continuethiscode...',PHP_EOL;}//code:200;TestException:Thisistest2Error...//继续这段代码...说了这么多,最后还是结合上面的内容来处理除0错误抛出的异常。文章开头提到,错误是应该避免的,异常属于逻辑业务。所以当我们接收到一个需要划分的参数时,我们可以先判断这个数字是否为0,如果为0,就会抛出异常,让上层调用者处理。如果不为0,则正常划分。足够的。functiontest3($d){if($d==0){thrownewException('除数不能为0');}return1/$d;}try{echotest3(2),PHP_EOL;}catch(Exception$e){echo'Exception:'.$e->getMessage(),PHP_EOL;}finally{echo'finally:继续!',PHP_EOL;}//0.5//最后:继续执行!尝试{echotest3(0),PHP_EOL;}catch(Exception$e){echo'Exception:'.$e->getMessage(),PHP_EOL;}finally{echo'finally:继续执行!',PHP_EOL;}//异常:除数不能为0//finally:继续执行!这是对异常相关使用的总结。通过这两篇文章,相信大家对PHP错误和异常有了一些直观的认识。在下一篇文章中,我们将把错误和异常放在一起进行比较,并说明PHP7对错误做了哪些改进。内容依旧精彩,值得期待!!测试代码:https://github.com/zhangyue0503/dev-blog/blob/master/php/202002/source/%E4%B8%80%E8%B5%B7%E6%90%9E%E6%87%82PHP%E7%9A%84%E9%94%99%E8%AF%AF%E5%92%8C%E5%BC%82%E5%B8%B8%EF%BC%88%E4%BA%8C%EF%BC%89.php参考文档:https://www.cnblogs.com/init-007/p/11242813.htmlhttps://www.php.net/manual/zh/language.exceptions.phphttps://www.php.net/manual/zh/class.exception.phphttps://www.php.net/manual/zh/language.exceptions.extending.php============各媒体平台可以搜索【硬核项目经理】
