什么是输出缓冲,为什么要在PHP中使用它?


当前回答

ob_start();  // turns on output buffering
$foo->bar();  // all output goes only to buffer
ob_clean();  // delete the contents of the buffer, but remains buffering active
$foo->render(); // output goes to buffer
ob_flush(); // send buffer output
$none = ob_get_contents();  // buffer content is now an empty string
ob_end_clean();  // turn off output buffering

缓冲区可以嵌套,因此当一个缓冲区处于活动状态时,另一个ob_start()会激活一个新的缓冲区。因此ob_end_flush()和ob_flush()并不是真正地将缓冲区发送到输出,而是发送到父缓冲区。只有当没有父缓冲区时,才会将内容发送到浏览器或终端。

这里有很好的解释:https://phpfashion.com/everything-about-output-buffering-in-php

其他回答

我知道这是一个老问题,但我想把我的答案写下来给视觉学习者。我在万维网上找不到任何解释输出缓冲的图表,所以我自己在Windows mspaint.exe中做了一个图表。

如果输出缓冲被关闭,那么echo将立即向浏览器发送数据。

如果打开了输出缓冲区,那么echo会在将数据发送到浏览器之前将数据发送到输出缓冲区。

phpinfo

要查看输出缓冲是否打开/关闭,请参考核心部分的phpinfo。output_buffering指令将告诉你Output buffering是否打开/关闭。

在本例中,output_buffering值为4096,这意味着缓冲区大小为4 KB。它还意味着在Web服务器上打开了输出缓冲。

php . ini

可以通过改变output_buffering指令的值来打开/关闭和改变缓冲区大小。只需在php.ini中找到它,将其更改为您选择的设置,并重新启动Web服务器。你可以在下面找到我的php.ini示例。

; Output buffering is a mechanism for controlling how much output data
; (excluding headers and cookies) PHP should keep internally before pushing that
; data to the client. If your application's output exceeds this setting, PHP
; will send that data in chunks of roughly the size you specify.
; Turning on this setting and managing its maximum buffer size can yield some
; interesting side-effects depending on your application and web server.
; You may be able to send headers and cookies after you've already sent output
; through print or echo. You also may see performance benefits if your server is
; emitting less packets due to buffered output versus PHP streaming the output
; as it gets it. On production servers, 4096 bytes is a good setting for performance
; reasons.
; Note: Output buffering can also be controlled via Output Buffering Control
;   functions.
; Possible Values:
;   On = Enabled and buffer is unlimited. (Use with caution)
;   Off = Disabled
;   Integer = Enables the buffer and sets its maximum size in bytes.
; Note: This directive is hardcoded to Off for the CLI SAPI
; Default Value: Off
; Development Value: 4096
; Production Value: 4096
; http://php.net/output-buffering
output_buffering = 4096

指令output_buffering并不是唯一关于输出缓冲的可配置指令。你可以在这里找到其他可配置的输出缓冲指令:http://php.net/manual/en/outcontrol.configuration.php

例如:ob_get_clean ()

下面你可以看到如何捕获一个回声,并在将它发送到浏览器之前对它进行操作。

// Turn on output buffering  
ob_start();  

echo 'Hello World';  // save to output buffer

$output = ob_get_clean();  // Get content from the output buffer, and discard the output buffer ...
$output = strtoupper($output); // manipulate the output  

echo $output;  // send to output stream / Browser

// OUTPUT:  
HELLO WORLD

示例:Hackingwithphp.com

更多关于输出缓冲区的示例信息可以在这里找到:

http://www.hackingwithphp.com/13/0/0/output-buffering

2019年更新。如果你有专用服务器和SSD或更好的NVM, 3.5GHZ。你不应该使用缓冲来让加载速度更快的网站在100 -150毫秒。

由于网络比2019年使用性能服务器(服务器,内存,磁盘)和打开APC PHP处理脚本慢,生成脚本有时只需要70ms,另一次仅是网络需要时间,从10ms到150ms从位于用户服务器。

所以如果你想要快150ms,缓冲就会变慢,因为需要额外的缓冲数据收集,这会产生额外的成本。10年前,当服务器制作1s脚本时,它很有用。

请小心output_buffering有限制,如果你想使用jpg加载它会自动刷新和崩溃发送。

欢呼。

你可以制造快速的河流 或 你可以安全地做tama:)

ob_start();  // turns on output buffering
$foo->bar();  // all output goes only to buffer
ob_clean();  // delete the contents of the buffer, but remains buffering active
$foo->render(); // output goes to buffer
ob_flush(); // send buffer output
$none = ob_get_contents();  // buffer content is now an empty string
ob_end_clean();  // turn off output buffering

缓冲区可以嵌套,因此当一个缓冲区处于活动状态时,另一个ob_start()会激活一个新的缓冲区。因此ob_end_flush()和ob_flush()并不是真正地将缓冲区发送到输出,而是发送到父缓冲区。只有当没有父缓冲区时,才会将内容发送到浏览器或终端。

这里有很好的解释:https://phpfashion.com/everything-about-output-buffering-in-php

顾名思义,这里的内存缓冲区用于管理脚本的输出如何出现。

这里有一个关于这个主题的很好的教程

PHP使用输出缓冲来提高性能并执行一些技巧。

您可以让PHP将所有输出存储到缓冲区中,并一次性输出所有输出,从而提高网络性能。 在某些情况下,您可以访问缓冲区内容而无需将其发送回浏览器。

想想这个例子:

<?php
    ob_start( );
    phpinfo( );
    $output = ob_get_clean( );
?>

上面的示例将输出捕获到一个变量中,而不是将其发送到浏览器。默认情况下,Output_buffering是关闭的。

当您希望在发送内容后修改标头时,可以使用输出缓冲。

想想这个例子:

<?php
    ob_start( );
    echo "Hello World";
    if ( $some_error )
    {
        header( "Location: error.php" );
        exit( 0 );
    }
?>