所以场景是我有一个使用输出缓冲的应用程序,除了预期的结果之外,应用程序还返回一些额外的数据。我可以操作将预期结果添加到输出缓冲区的点,以确认在应用程序的此时,发送到输出缓冲区的数据是正确的,因此意外的额外数据必须来自另一个源。 / p>
我怀疑问题是一个不在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
函数会是什么样子。所以这个问题不是特定于应用程序的,我只是试图找到拦截输出函数(回声,打印等)的通用方法,并获得有关输出调用源自何处的信息。
答案 0 :(得分: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_end_clean清除缓冲区在你的ob_start之前。
ob_end_clean();
ob_start();
4
关闭标记后查找所有PHP空格:
pcregrep -rMl '\?>[\s\n]+\z' *
OR
pcregrep -rM '\?>[\s]+[^\S]*$' *.php