为什么debug_backtrace() 有时不包括行号?

2022-08-30 23:30:42

我发现有时不包括呼叫的线路号码。为什么会这样,有什么原因,有什么方法可以纠正它吗?debug_backtrace()

提前致谢。

P.S.是的,省略行号的调用是我自己的代码,而不是内部PHP代码。


答案 1

请考虑以下代码:

<?
class BtTest
{
  public function getTheItem()
  {
    var_dump( debug_backtrace( false ) );
    $bt = debug_backtrace( false );
    return $bt[1];
  }

  public function __call( $methodName, $methodArgs )
  {
    return $this->getTheItem();
  }
}

$o = new BtTest();
$bti = $o->test();

assert( 'array_key_exists("function", $bti)' );
assert( 'array_key_exists("line", $bti)' );
assert( 'array_key_exists("file", $bti)' );

执行上述示例将生成以下输出:

array(3) {
  [0]=>
  array(6) {
    ["file"]=>
    string(53) "/somewhere/in/the/filesystem/tests/bt-test-so.php"
    ["line"]=>
    int(13)
    ["function"]=>
    string(10) "getTheItem"
    ["class"]=>
    string(6) "BtTest"
    ["type"]=>
    string(2) "->"
    ["args"]=>
    array(0) {
    }
  }
  [1]=>
  array(4) {
    ["function"]=>
    string(6) "__call"
    ["class"]=>
    string(6) "BtTest"
    ["type"]=>
    string(2) "->"
    ["args"]=>
    array(2) {
      [0]=>
      &string(4) "test"
      [1]=>
      &array(0) {
      }
    }
  }
  [2]=>
  array(6) {
    ["file"]=>
    string(53) "/somewhere/in/the/filesystem/tests/bt-test-so.php"
    ["line"]=>
    int(18)
    ["function"]=>
    string(4) "test"
    ["class"]=>
    string(6) "BtTest"
    ["type"]=>
    string(2) "->"
    ["args"]=>
    array(0) {
    }
  }
}
PHP Warning:  assert(): Assertion "array_key_exists("line", $bti)" failed in /somewhere/in/the/filesystem/tests/bt-test-so.php on line 21
PHP Warning:  assert(): Assertion "array_key_exists("file", $bti)" failed in /somewhere/in/the/filesystem/tests/bt-test-so.php on line 22

第一个回溯项(索引 0)间接(通过 和 项)表示该方法是从该方法调用的。linefilegetTheItem__call

第二个回溯项(索引 1)表示该方法是从某个位置(缺少和项)调用的。__calllinefile

第三个回溯项(索引 2)表示该方法是从脚本的全局范围调用的。test

方法调用的位置可能位于 php 解释器代码中某个位置的某个方法解析代码中。修复它有两种可能性。第二项应引用解释器的源代码文件和行,或者第二项和第三项应合并为一个。我个人更喜欢第二种解决方案,因为解释器的内部对我来说并不有趣(这就是他们在python的回溯中似乎就是这样做的),但是我知道有时第一个解决方案会提供更明确的跟踪(特别是当它是从内部调用的回调时)。__call

因此,似乎负责(或至少维护)函数代码的开发人员并不认为它是一个错误,或者可能没有简单的方法来修复它。可以使用一些占位符值填充 和 项(例如 ,甚至在文档中强调它。除非有人能成功地说服他们这样做,否则你只需要在代码中处理特殊情况。debug_backtracelinefile<unknown-file>0

我在上面写这篇文章只是为了分享我对函数的奇怪行为的理解。如果有人愿意为一个稍微好一点的世界而战,这里有一些相关的错误报告的链接:

最早的报告来自2003年,所以你不应该指望快速修复:)


答案 2

我认为这被列为PHP错误

调试回溯跟踪显示调用脚本的文件名和行号。如果从内部函数内部调用函数(可能作为回调),则不能设置文件名和 lineno。


推荐