如何跟踪对输出缓冲区的调用

问题描述 投票:0回答:1

所以场景是我有一个使用输出缓冲的应用程序,除了预期的结果之外,应用程序还返回一些额外的数据。我可以操作将预期结果添加到输出缓冲区的点,以确认在应用程序的此时,发送到输出缓冲区的数据是正确的,因此意外的额外数据必须来自另一个源。

我怀疑这个问题是一个不在PHP脚本标签内的流浪角色,但我没有运气弄清楚哪个(如果有的话)文件是罪魁祸首。据我所知,可能有一些文件被包含在内,实际上正在做一个额外数据的显式echo

所以我希望捕获写入输出缓冲区的任何文件的文件名和行号,但这比我预期的要困难得多。我知道最初的ob_start在哪里,所以我一直在尝试使用自定义的output_callback。以下是我已经尝试过的一些事情:

ob_start(function($string) { 
    return __FILE__ . ":" . __LINE__ . " : " $string; 
});

这将返回定义函数的文件名和行号,而不是调用它的位置(正如预期的那样,我猜,但是开始时是错误的)。

ob_start(function($string) { 
    return print_r(debug_print_backtrace(), true) . " : " $string; 
});

这会抛出一个关于破坏lambda函数的错误。

ob_start(function($string) { 
    return var_dump(debug_backtrace()) . " : " $string; 
});

结果好坏参半。我承认我不完全确定原因。但在大多数情况下,var_dump解析为一个空字符串(没有),但在一种情况下,它似乎生成一些跟踪数组,但没有任何反映ob_start调用的起源(换句话说,无论输出什么,实际上调用echo的源文件不是跟踪的一部分)。

请记住,通过上述内容,我一直在进行一些非常基本的测试,以确定当我准备将其放入故障排除上下文时,自定义output_callback函数的样子。所以问题不是特定于应用程序,我只是想找到一种截取输出函数(echo,print等)的通用方法,并获取有关输出调用源自何处的信息。

php output-buffering debug-backtrace
1个回答
1
投票

可能的解决方案

1

如果您的代码使用输出缓冲来吐出该流浪角色,则下面的解决方案可以提供帮助。你也是对的,它只能在刷新/检索输出缓冲时工作,而不是在每个print / echo语句中工作。此外,所有本机函数在回调函数中都不起作用,而print_r就是其中之一,但我们可以抛出Exception。请尝试以下代码,看看它是否有助于您解决问题。

ob_start(function($buffer) {
    try {
        $stackTrace = debug_print_backtrace();
        throw new \Exception($stackTrace, 1);
    } catch (\Exception $ex) {
        //This line can be logged to a file instead of appending to the buffer
        $buffer .= PHP_EOL.$ex->getTraceAsString().PHP_EOL.PHP_EOL;
    }
    return $buffer;
});

2

如果第一个解决方案无法解决您的问题,您可能需要使用高级调试和分析工具,如Xdebug

3

如果您真的不关心在当前行之前已经回显的内容,或者您​​希望将来证明类似问题未来不会发生,您可以在ob_start之前使用ob_end_clean清除缓冲区。

ob_end_clean();
ob_start();

4

关闭标记后查找所有PHP空格:

pcregrep -rMl '\?>[\s\n]+\z' *

要么

pcregrep -rM '\?>[\s]+[^\S]*$' *.php
© www.soinside.com 2019 - 2024. All rights reserved.