php – error_get_last()和自定义错误处理程序

odbc_errormsg
不会按照预期的方式报告 odbc_execute错误消息.它只是抛出一个警告.所以我被迫编写了一个hack来通过 error_get_last解析错误消息.

我正在使用set_error_handler并且error_get_last返回NULL,除非我:

>禁用我的错误处理程序,
>或使其返回FALSE.

我认为这是由于PHP的内置错误处理程序负责将错误详细信息存储在某处,以便以后可以检索它们.

有没有办法在我的自定义错误处理程序中模拟这种行为,所以error_get_last()可以正常使用?

请注意我已经知道几种方法可以随时检索错误信息.我的问题是如何使error_get_last可用.

更新:我想我最好发布一些代码.

PHP有error_get_last(),允许这样做:

@fopen('xxx');
var_dump( error_get_last() );

……得到这个:

array(4) {
  ["type"]=>
  int(2)
  ["message"]=>
  string(46) "fopen() expects at least 2 parameters,1 given"
  ["file"]=>
  string(69) "C:\Documents and Settings\ALVARO.GONZALEZ\Mis documentos\tmp\test.PHP"
  ["line"]=>
  int(3)
}

如果您替换内置错误处理程序,这会中断:

function custom_error_handler($errno,$errstr,$errfile,$errline){
    $ignore = ($errno & error_reporting()) == 0;
    if(!$ignore){
        echo "[Error happened: $errstr]\n";
    }
    return TRUE;
}
set_error_handler('custom_error_handler');

@fopen('xxx');
var_dump( error_get_last() ); // NULL

如果你保留两个错误处理程序……

function custom_error_handler($errno,$errline){
    $ignore = ($errno & error_reporting()) == 0;
    if(!$ignore){
        echo "[Error happened: $errstr]\n";
    }
    return FALSE;
}
set_error_handler('custom_error_handler');

error_reporting(E_ALL);
echo $foo;

……你有副作用:

[Error happened: Undefined variable: foo]

Notice: Undefined variable: foo in C:\Documents and Settings\ALVARO.GONZALEZ\Mis documentos\tmp\test.PHP on line 15

Call Stack:
    0.0004     329720   1. {main}() C:\Documents and Settings\ALVARO.GONZALEZ\Mis documentos\tmp\test.PHP:0

……而不仅仅是:

[Error happened: Undefined variable: foo]

我希望自定义错误处理程序与error_get_last正确连接.我希望error_get_last正常工作.

对,这是一个奇怪的解决方案,但我认为它将适合您的目的.

经过一段时间的游戏,我发现了这个:

function my_error_handler ($errno,$errfile = '',$errline = 0,$errcontext = array()) {

  // Handle the error here

  @trigger_error($errstr);
  return TRUE;

}

// Just to make sure PHP is not outputting anything
error_reporting(-1);
ini_set('display_errors',1);

set_error_handler('my_error_handler');

// An E_USR error...
trigger_error('Some error');
var_dump(error_get_last());

// ...and a native one
$key = count();
var_dump(error_get_last());

结果如下:

array(4) {
  ["type"]=>
  int(1024)
  ["message"]=>
  string(10) "Some error"
  ["file"]=>
  string(69) "C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\test.PHP"
  ["line"]=>
  int(7)
}
array(4) {
  ["type"]=>
  int(1024)
  ["message"]=>
  string(45) "count() expects at least 1 parameter,0 given"
  ["file"]=>
  string(69) "C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\test.PHP"
  ["line"]=>
  int(7)
}

错误处理程序中调用@trigger_error()并且不返回FALSE会导致error_get_last()返回除NULL之外的其他内容,但由于使用@抑制了错误,因此PHP不会输出任何内容.似乎为了避免无限递归,从注册错误处理函数调用trigger_error()不会调用错误处理程序 – 这对我们有利.

显然,错误代码已被修改,但如果需要,您可以将其转换为相关的E_USR_ *代码 – 但我怀疑您真正想要的是字符串值,此方法允许您获取.遗憾的是,您还丢失了行号和文件信息 – 尽管您可以通过在错误处理程序中执行涉及堆栈跟踪的操作来获取此信息,或者至少将其包含在传递的参数的字符串中.

这是一个可怕的,可怕的,可怕的黑客攻击 – 但由于没有官方认可的方法来做到这一点,黑客本质上就是你所要求的.

相关文章

统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
前言 之前做了微信登录,所以总结一下微信授权登录并获取用户...
FastAdmin是我第一个接触的后台管理系统框架。FastAdmin是一...
之前公司需要一个内部的通讯软件,就叫我做一个。通讯软件嘛...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...