php异常机制

最近在扩展抓取pdo的时候发现了点问题,发现有的是报异常,有的是不报,

  <?php
error_reporting(E_ALL ^ E_DEPRECATED);

try{
 $opts = array(PDO::ATTR_AUTOCOMMIT=>0, PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION, PDO::ATTR_AUTOCOMMIT=>0,PDO::ATTR_TIMEOUT => 3,);
  $pdo = new PDO("mysql:host=127.0.0.1;port=3306;dbname=test;charset=UTF8","root","root",$opts);

 $rs = $pdo -> query("select * from bankaa");
   }
   catch(exception $e){
   print_r($e);exit;
   }
  

在我的底层扩展是能抓到EG(exception)的,但是同事用了个底层php框架类,就抓不到了,最后跟踪断点发现


跟踪到


发现了一个变量

PDO::ERRMODE_SILENT

此为默认模式。 PDO 将只简单地设置错误码,可使用 PDO::errorCode() 和  PDO::errorInfo()方法来检查语句和数据库对象。如果错误是由于对语句对象的调用而产生的,那么可以调用那个对象的  PDOStatement::errorCode() 或 PDOStatement::errorInfo() 方法。如果错误是由于调用数据库对象而产生的,那么可以在数据库对象上调用上述两个方法。

PDO::ERRMODE_WARNING

除设置错误码之外,PDO 还将发出一条传统的 E_WARNING 信息。如果只是想看看发生了什么问题且不中断应用程序的流程,那么此设置在调试/测试期间非常有用。

PDO::ERRMODE_EXCEPTION (注意:它会内部自己抛出异常,终断页面)

恍然大悟,我的自己模拟的例子是制定了异常属性。
怪不得可以抓到异常,但是第三方类库抓不到,于是扩展里我做了兼容。

顺便做了下总结说一下php异常机制:如下图:


这个图就把一个throw抛出异常以及到抓到catch异常的整个流程分析的很清楚。

zend_throw_exception_internal就相当于手动的throw一个异常,如果是php代码的话一般会有见到这样一个ZEND_THROW_SPEC_CV_HANDLER

但最终调用的都是zend_throw_exception_internal

在这个函数过后,会跳到一个ZEND_HANDLE_EXCEPTION_SPEC_HANDLER也就是我们经常发现的会跳到每一个op array的最后一行, 来执行这条ZEND_HANDLE_EXCEPTION,在这个函数中会判断如果是异常则把下一条要执行的op line, 置为第一个catch的op line, 并继续执行.如果不是  则销毁一些不需要的变量, 和opline,  然后直接结束执行过程.

如果有被catch到就会执行ZEND_CATCH_SPEC_CONST_CV_HANDLER,从而把EG(exception)=NULL

如果没有被catch,层层向上抛,最后就会发现最后调用zend_leave_helper_SPEC,离开函数。


在退出真正的执行之前,还有一层判断,就是有没有自定义的异常处理,如果有继续执行,没有直接退出运行。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值