debug_backtrace()追踪显示抽象类而非具体类,如何解决?
解决debug_backtrace显示抽象类而非子类的问题
问题出在默认的debug_backtrace()不会返回调用时的实际对象实例,所以class字段只会显示方法定义所在的抽象类名称。要获取实际子类名称,可通过以下修改解决:
关键调整
- 调用
debug_backtrace时添加DEBUG_BACKTRACE_PROVIDE_OBJECT参数,获取调用上下文的对象实例 - 对每个调用栈元素,若存在
object字段,用get_class($call['object'])获取实际子类名称,替代原有的抽象类名
修改后的完整代码
function debug_backtrace_string($skip = 1) { try { // 添加参数获取调用时的对象实例 $calls = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT); $calls = array_slice($calls, $skip); $str = []; foreach ($calls as $call) { if (isset($call['args'])) foreach ($call['args'] as $k => $v) $call['args'][$k] = gettype($v).' "'.substr($v, 0, 100).'"'; else $call['args'] = []; // 获取实际调用的类名:有对象实例则用子类名,否则用原有class字段 $actualClass = ''; if (isset($call['object'])) { $actualClass = get_class($call['object']); } elseif (isset($call['class'])) { $actualClass = $call['class']; } $str[] = ($call['file']??'') .(isset($call['line'])?' ('.$call['line'].')':'') ." ".$actualClass.($call['type']??'').$call['function'] .'('.implode(', ', $call['args']).')'; } return implode("\n", $str); } catch (Throwable $e) { return "debug_backtrace_string($skip) failed: ".$e; } }
补充说明
- 调用抽象类的实例方法时,
$call['object']会指向实际的子类对象,get_class()就能返回子类名称 - 静态方法调用不存在
object字段,会 fallback 到原有的class字段值(此时若静态方法定义在抽象类中,仍会显示抽象类名,这是PHP静态调用的正常行为)
内容的提问来源于stack exchange,提问作者Jayy
相关产品推荐
相关产品推荐

