dongzhuo5425 2017-12-14 03:15
浏览 34

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

So the scenario is that I have an application that uses output buffering, and the application is returning some extra data in addition to the expected results. I can manipulate the point where the expected results are being added to the output buffer to confirm that at this point in the application, the data being sent to the output buffer is correct, thus the unexpected extra data must be coming from another source.

I suspect that the issue is a stray character that is not inside the PHP script tags, but I'm having no luck figuring out which (if any) files is the culprit. For all I know, there could be some file that is being included that is actually doing an explicit echo of the extra data.

So I was hoping to capture the filename and line number of any file that writes to the output buffer, but this is proving much more difficult than I expected. I know where the initial ob_start is, so I've been trying to use a custom output_callback. Here are a few things I've tried already:

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

This returns the filename and line number where the function is defined, not where it was called from (as expected, I guess, but off to a bad start).

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

This throws an error about destroying a lambda function.

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

This had mixed results. I will admit I'm not totally sure why. But in most cases the var_dump resolved to an empty string (nothing), but in one case, it seemed to generate some trace array, but didn't have anything reflecting the origin of the ob_start call (in other words, whatever it output, the source file that actually called the echo wasn't part of the trace).

Keep in mind that with the above, I have been doing some pretty basic testing just to figure out what the custom output_callback function would look like for when I'm ready to drop it into a troubleshooting context. So the issue isn't application-specific, I'm just trying to find a generic way to intercept output functions (echo, print, etc) and get information on where that output call originated.

  • 写回答

1条回答 默认 最新

  • dongmen5867 2017-12-14 03:35
    关注

    Possible Solutions

    1

    If you your code is using output buffering to spit out that stray character, the below solution can help. You are also right, that it will only work when the output buffering is flushed/retrieved, not at every print/echo statement. Also, all the native functions do not work in the call back function and print_r is one of them, but we can throw Exception. Please try the below code and see if it helps you in resolving your issue.

    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

    If the first solution does not help resolve your issue, you might want to use advanced debugging and profiling tools like Xdebug

    3

    If you really don't care about the content that is already being echoed out before the current line or if you want to future proof that the similar issue does not happen in future you can just flush out the buffer using ob_end_clean before your ob_start.

    ob_end_clean();
    ob_start();
    

    4

    Finding all PHP white space after closing tag:

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

    OR

    pcregrep -rM '\?>[\s]+[^\S]*$' *.php
    
    评论

报告相同问题?

悬赏问题

  • ¥15 BP神经网络控制倒立摆
  • ¥20 要这个数学建模编程的代码 并且能完整允许出来结果 完整的过程和数据的结果
  • ¥15 html5+css和javascript有人可以帮吗?图片要怎么插入代码里面啊
  • ¥30 Unity接入微信SDK 无法开启摄像头
  • ¥20 有偿 写代码 要用特定的软件anaconda 里的jvpyter 用python3写
  • ¥20 cad图纸,chx-3六轴码垛机器人
  • ¥15 移动摄像头专网需要解vlan
  • ¥20 access多表提取相同字段数据并合并
  • ¥20 基于MSP430f5529的MPU6050驱动,求出欧拉角
  • ¥20 Java-Oj-桌布的计算