/首页
/开源
/关于
老旧话题:PHP异常与错误的恩怨情仇
发表@2018-09-13 09:15:22
更新@2023-01-21 22:47:40
其实php的异常和错误真的没有什么恩怨情仇,因为php的异常你可以认为可能就是一坨狗屎。。。半坨吧,半坨。相对来说,更有利用价值的还是php的错误。所以,这两位之间也很难扯上什么恩怨情仇。 事情到这里,得先搞明白异常和错误到底有什么区别? 大部分php仁兄可能到现在接触php异常除了在刚学习异常那会儿认识了这个单词外,后来就再也没有接触过了。 能用好php异常的人,都一定日常生活中非常讲究的人,因为如果用错误那妥妥到处都是一坨又一坨的if else来判断错误。用异常的人大概有如下三种想法: - 搞不明白具体哪个地方会出问题,但感觉一定会特么出问题 - 想将X个php操作捆绑成一个事务,出问题后集体用优雅方式回滚 - 从Java过来的家伙,临时兼职搞几天php 在php里,异常有个基类叫做Exception,有两个常用的方法getLine()(获取出错的代码在第几行)和getMessage()(获取错误信息是什么),除此之外,这个基类基本上就是个空壳子了。你可以自己声明一个类继承这个类,然后自己实现异常抛出的定制化,而且这也应该是常用的正确的用法。一般情况下,异常用法如下: ```php getLine().' : '.$e->getMessage().PHP_EOL; } ``` 举个常见的案例,我们phhp curd们经常会遇到的问题:我们先向七牛云上传一张图片,上传成功后再把文件名称记录到数据库中。 - 文件上传成功了,但是插入数据库失败,浪费空间 - 文件上传失败了,但是插入数据库成功,悲惨世界 我们希望这两个操作是具备“事务”性质的。传统方式下,包括我在内都会这么写(伪代码): ```php getLine().' : '.$e->getMessage().PHP_EOL; } catch ( mysqlException $e ) { echo $e->getLine().' : '.$e->getMessage().PHP_EOL; } ``` 事情发展到这里,是包不住了,一定会有有识之士问:“ 除了可以简单模拟事务外,似乎跟我用传统的if else感觉差不多,都是我预知这个地方有错误然后我用throw抛出去处理,好像也没什么其他值得吹嘘的地方 ”。这个锅,php是背定了!我修改一下代码,如下面所示: ```php getLine().' : '.$e->getMessage().PHP_EOL; } catch ( mysqlException $e ) { echo $e->getLine().' : '.$e->getMessage().PHP_EOL; } ``` 如果说,执行upload2qiniu或者insert2mysql这两个函数,出问题后能够被捕捉到,是不是明显感觉不一样了?有没有感觉到高端大气优雅有气质上档次?!如果没有感觉到,你也要强行回答:是的! 但是,问题来了,这两个函数如何才能在出问题的时候抛出异常呢?这个时候,回到篇头的flag:“ php的异常可能是半坨屎 ”。因为更多时候,php代码出了问题,php更多是抛出**错误**而不是抛出**异常**!有些时候,php会抛出异常而非错误,更多时候php会现实错误而不是异常,还有一些情况php既现实错误又抛出异常。这就导致我们在想用异常的时候不得不采用手动抛出异常,然而,既然是手动抛出异常,那就必定是我们可以提前预知到这里可能会出问题,抛出异常失去了最大的意义! 那么,怎么办?难道我要在upload2qiniu和insert2mysql两个函数中手动抛出异常吗?这也太狗屎了!如何让php在遇到错误的时候也能抛出异常呢?这个时候,我们要引入一个php函数了:set_error_handle( '自定义错误处理函数', '错误级别' )。简单说来,这个函数 可以让我们自定义当php遇到某个错误级别的错误时候该怎么办。 现在有如下代码(为了避免混淆视听,我们在php配置文件关闭display_error): ```php