php异常机制

    xiaoxiao2021-03-25  89

    最近在扩展抓取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,离开函数。

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

    转载请注明原文地址: https://ju.6miu.com/read-25400.html

    最新回复(0)