考虑以下代码:
<?
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)间接表明(通过 line 和 file 项)getTheItem 方法是从 __call 方法调用的。
第二个回溯项(索引 1)表示 __call 方法是从某处调用的(缺少 line 和 file 项)。
第三个回溯项(索引 2)表示 test 方法是从脚本的全局范围调用的。
__call 方法调用的位置可能在 php 解释器代码中的某个方法解析代码中。修复它有两种可能性。第二个项目应该引用解释器的源代码文件和行,或者第二个和第三个回溯项目应该合并为一个。我个人更喜欢第二种解决方案,因为解释器的内部对我来说并不有趣(这就是他们在 python 的回溯中似乎是这样做的),但是我知道有时第一种解决方案提供更明确的跟踪(特别是当它是一个回调时)从内部调用)。
如此左右,似乎负责(或至少维护)debug_backtrace 函数代码的开发人员并不认为它是一个错误,或者可能没有简单的方法来修复它。可以用一些占位符值(例如 <unknown-file> 和 0 甚至 nulls)填充 line 和 file 项目并在文档中强调它。 除非有人成功说服他们这样做,否则你只需要处理代码中的特殊情况。
我写上面只是为了分享我对函数奇怪行为的理解。如果有人愿意为更美好的世界而奋斗,这里是一些相关错误报告的链接:
最早的报告是 2003 年的,所以你不应该指望快速修复 :)