ErrorException返回错误的文件和行

时间:2012-07-20 16:53:31

标签: php exception

在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,在第2行和第2行的file3.php中调用   定义...

消息是正确的,但是当我尝试使用$exception->getFile()$exception->getLine()(在我的异常处理程序中)获取文件和行时,我得到foo()定义的文件和行,不是它被称为......

但是使用本机PHP函数,我得到调用函数的文件和行(这就是我想要的)。

2 个答案:

答案 0 :(得分:2)

它首先归结为最接近的。

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

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

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

答案 1 :(得分:1)

好问题!

对于本机和用户定义的函数,事情看起来似乎有所不同。但是,一个显而易见的事情是,如果它是原生的,那么它真的可以告诉你函数的定义,因为它是用C编写的,而不是PHP编写的。在用户空间代码的情况下,很高兴找到它被调用的位置。一种方法是从捕获的异常中解析该错误消息,您可以获取创建它的文件和行。

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