ErrorException返回错误的文件和行


ErrorException returns wrong file and line

在file1.php:中

set_error_handler('my_error_handler');
set_exception_handler('my_exception_handler');
function my_error_handler($errNo, $errStr, $errFile, $errLine, $whatever = null){
  // here ErrFile and $errLine are correct only for native funcs...
  throw New ErrorException($errStr, 0, $errNo, $errFile, $errLine);
}
function my_exception_handler($exception){
  print $exception->getLine(); // correct only for native functions
  print $exception->getFile(); // correct only for native functions
}

在file2.php中,有一个示例函数定义:

function foo($requiredArg){
}

在file3.php中,调用foo:

  foo();

生产:

foo()缺少参数1,在file3.php的第2行调用定义

消息是正确的,但当我尝试获取带有$exception->getFile()$exception->getLine()的文件和行(在我的异常处理程序中)时,我会获取定义foo()的文件和行将,而不是调用它的位置。。。

但是使用本机PHP函数,我可以获得调用该函数的文件和行(这正是我想要的)。

它简单地归结为最接近的第一个。

当您使用核心或内置函数时,它们的定义包含在PHP的核心中。这意味着,与用户定义函数相比,函数的定义是不可用的,因为用户定义函数的定义很容易获得。

如果在引用用户定义函数错误的exception_handler函数中运行debug_backtrace();$exception->getTrace();,您将首先看到函数的定义,然后看到函数的调用。如果你调用一个内部函数,你只会看到调用行,因为PHP无法告诉你脚本或包含文件中定义了内部函数的代码行,因为它是在核心中定义的。

这是错误处理的操作顺序。如果您想获得调用该函数的实际行,可以查看跟踪并获取第二个数组对行号的引用。

好问题!

对于本机函数和用户定义函数,情况似乎有所不同。不过,有一点很明显,如果函数是本机函数,就不能真正告诉你它是在哪里定义的,因为它是用C编写的,而不是用PHP编写的。如果是用户空间代码的话,如果能找到它是在哪里调用的,那就太好了。一种方法是从捕获的Exception中解析错误消息,您可以获得创建它的文件和行。

function my_exception_handler($exception)
{
    $message = $exception->getMessage();
    $file    = $exception->getFile();
    $line    = $exception->getLine();
    if(strpos($message, 'called in') !== false) {
        preg_match('/called in .*php/', $message, $matches);
        $file = str_replace('called in ', '', $matches[0]);
        preg_match('/on line 'd/', $message, $matches);
        $line = str_replace('on line ', '', $matches[0]);
    }
    echo 'line: ' . $line . PHP_EOL;
    echo 'file: ' . $file . PHP_EOL;
}

修改my_exception_handler:的基于输出的问题描述

line: 4
file: /tmp/file3.php