【问题标题】:start output buffering in one class method and end it in another class method在一个类方法中开始输出缓冲并在另一个类方法中结束它
【发布时间】:2014-07-06 07:30:02
【问题描述】:

我已经用 php 编程很多很多年了,并且在我的几个类和类方法中使用了输出缓冲。最近,在写一个模板类的时候,我的思绪开始漫游。以下是我的想法:

这只是一个例子。

class someClass {
    protected $contents;

    public function __construct() {
        ob_start();
        // execute some code here.
    }

    private function someMethod() {
        // execute some code here.
        $this->contents = ob_get_contents();
    }

    public function someOtherMethod() {
        ob_end_clean();
        echo $this->contents;
    }
}  

考虑上面的示例代码。

问题

  • 可以这样使用输出缓冲吗?
  • 使用输出缓冲可以防止在发送标头之前写入代码,但是如果有的话,还有什么其他好处呢?
  • 如果可行,是否可行?

【问题讨论】:

  • 你试过了吗?为什么它不起作用?
  • 老实说,我还没有尝试过。当我已经编写了几个小时并试图保持专注时,我往往很容易分心......我只是想我会在这里问我的问题,这样我就可以继续我目前的任务。看起来它会起作用并且是合乎逻辑的,但它是否实用?测试这个可能要等到我完成我当前的项目。
  • 嗯,这是一个愚蠢的理由在这里问一个问题。请仅在您自己找不到答案时提​​出问题。
  • 它会起作用,ob_start() 是一个函数,并且在方法中调用的函数没有范围问题。它将像在其他任何地方一样打开输出缓冲。

标签: php


【解决方案1】:

调试是最大的好处,尤其是在响应 ajax 请求时(即,即使出现错误也必须返回有效的 json,当您无法控制另一个端点时)因此您可以缓存所有输出并且如果遇到关机(-通过- register_shutdown_function() )您将输出格式化为 json - 带有适当的错误和跟踪数据等。这是我最大的用途。你会遇到嵌套 ob_start 的问题。即使那样,这是否真的有用还是有争议的。将输出转储到文本文件中也可以很好地报告错误,但这与在方法中使用它不同,并且更依赖于您的项目需求。

我从事非常敏感的工作,需要隐藏 99% 的错误输出并将其记录为文本,并向最终用户显示一般错误;

这可能会为您省去一些麻烦

/**
     * dump all levels of ob_start into message
     * @return string
     */
    public static function obGetCleanNested(){
        $message = '';
        for($i=0; $i < ob_get_level(); $i++){
            $message .= ob_get_clean();
        }
        return $message;    
    }

【讨论】:

    【解决方案2】:
    class buffer {
    
            public $output;
    
            public function __construct($content) { 
                ob_start();
                $this->output = $content;
            }
    
            public function endBuffer() { 
                $buffer = ob_get_clean();
                $this->output = $buffer;
                echo $this->output . "<br>";
            }
    
            public function showBufferStatus() {
                if ($this->output == null) {
                    echo "nothing inside.";
                } else {
                    echo $this->output;
                }
            }
        }
    
        $buffer = new buffer("Test"); // starts buffer
        $buffer->showBufferStatus(); // checks content inside buffer
        $buffer->endBuffer(); // ends it
        echo "still there: ", $buffer->showBufferStatus(); // checks again
    

    基本上,现在使用ob_get_clean() 函数实际上可以节省一招,因此没有额外的方法。因为它同时执行ob_get_contents()ob_end_clean()

    【讨论】:

      【解决方案3】:

      “可以这样使用输出缓冲吗?”

      可以的

      “使用输出缓冲可以防止在发送标头之前编写代码,但是如果有的话,还有什么其他好处呢?”

      您可以简单地对输出进行任何操作(压缩/更改某些部分)

      **“如果可以的话,实用吗?”**

      这取决于需求。如果代码以正确的方式编写,在我看来,在大多数情况下,您可能不必使用输出缓冲。但是有时,特别是如果您想修改输出,使用输出缓冲非常方便

      【讨论】:

        【解决方案4】:

        可以这样使用输出缓冲吗?

        是的。

        使用输出缓冲可以防止在发送标头之前写入代码,但是 > 如果有的话,还有什么其他好处?

        这几乎是唯一的好处。

        如果可以的话,实用吗?

        这是一个见仁见智的问题。我的意见是不,其他人可能会说是,甚至其他人可能会说它没有“实际”效果,因为 php 并不真正关心您在哪里、为什么或多少次调用ob_start()ob_end_clean()

        【讨论】:

        • 你答案的最后一部分不正确。 PHP 确实关心ob_start 被调用了多少次。
        • ^ 我的立场是正确的。 Output buffers are stackable, that is, you may call ob_start() while another ob_start() is active. Just make sure that you call ob_end_flush() the appropriate number of times. If multiple output callback functions are active, output is being filtered sequentially through each of them in nesting order.
        • 看我的帖子 ob_get_level() 在这里非常有用,除非你只是flush() all
        【解决方案5】:

        答案

        • 当然,您可以这样使用它。为什么它不起作用?!
        • 其他好处是您可以抑制某些您根本不想输出的输出。在您的示例中,在someMethod() 内的$this-&gt;contents = ob_get_contents();someOtherMethod() 内的ob_end_clean(); 之间生成的所有输出将永远不会被输出。
        • 如果您故意不想输出某些代码,这可能会很实用。正如您所说,当然要延迟输出,直到发送标头。但请注意拨打ob_start() 的次数,因为每次都会更深一层。

        【讨论】:

        • 这回答了你的问题吗?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-02-02
        • 1970-01-01
        • 1970-01-01
        • 2011-06-17
        • 2021-03-24
        • 1970-01-01
        相关资源
        最近更新 更多