什么是输出缓冲?


Answers:


274

Web开发人员的输出缓冲,初学者指南

如果没有输出缓冲(默认),则HTML将通过脚本逐步地作为PHP进程发送到浏览器。使用输出缓冲,您的HTML存储在一个变量中,并在脚本末尾作为一个片段发送到浏览器。

Web开发人员的输出缓冲优势

  • 单独打开输出缓冲可减少下载和呈现HTML所需的时间,因为在PHP处理HTML时,不会将其分段发送给浏览器。
  • 我们可以用PHP字符串完成的所有花哨的工作,现在我们可以将整个HTML页面作为一个变量来处理。
  • 如果在设置Cookie时遇到过消息“警告:无法修改标题信息-标题已经由(输出)发送”,您将很高兴知道输出缓冲是您的答案。

6
+1。这是另一个有用的链接:php.net/manual/en/function.ob-start.php-在处理回显要存储在变量中的值的函数时也很有用。
凸轮

真的所有内容都缓冲到了最后,还是如果我的页面很长,页面是否会成块出现?
zedoo 2010年

5
@zedoo如果使用开始缓冲输出ob_start()实际上所有内容都会被缓冲。有一个可选的第二参数ob_start()int $chunk_size,其中,如果设置,将引起缓冲器到这会导致缓冲器的长度等于或超过这个尺寸的任何输出呼叫之后进行冲洗。
斧头。

12
如果收到“警告:无法修改标头信息”,则意味着您需要先审核代码,因为启用输出缓冲是问题的解决方法,而不是原因。轮到之前有东西在写。所以我不同意,但不足以使答案降低。
Glenn Plas

5
我仅看到使用缓冲的用法,为什么在php中默认未启用它?
Thomas Banderas

69

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 );
    }
?>

这里与Ax的问题相同:不是在不关闭输出缓冲的情况下就开始输出缓冲,这会使脚本遇到各种问题吗?
Edward Stumperd 2012年

1
当您调用刷新方法之一(例如ob_flush()ob_end_flush())时,将刷新缓冲区。当脚本突然,突然或以其他方式结束时,缓冲区的内容也将被刷新,因此不会有问题。
Salman

17

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

如果关闭输出缓冲,则将echo立即将数据发送到浏览器。

在此处输入图片说明

如果打开了输出缓冲,echo则会将数据发送到输出缓冲区,然后再将其发送到浏览器。

在此处输入图片说明

phpinfo

要查看是否打开/关闭输出缓冲,请参阅核心部分的phpinfo。该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()

在下面,您可以查看如何捕获echo和处理它,然后再将其发送到浏览器。

// 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


9

输出控制功能使您可以控制何时从脚本发送输出。这在几种不同的情况下很有用,尤其是在脚本开始输出数据之后需要将标头发送到浏览器的情况下。输出控制功能不影响使用header()或setcookie()发送的标头,仅影响诸如echo()和PHP代码块之间的数据之类的功能。

http://php.net/manual/zh/book.outcontrol.php

更多资源:

PHP的输出缓冲



1
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()and ob_flush()并不是真正将缓冲区发送到输出,而是发送到父缓冲区。并且只有当没有父缓冲区时,内容才会发送到浏览器或终端。

在这里很好地解释了:https : //phpfashion.com/everything-about-output-buffering-in-php


0

更新2019。如果您有专用的服务器和SSD或更好的NVM,则为3.5GHZ。您不应该使用缓冲在100ms至150ms的时间内使网站加载速度更快。

由于网络在2019年比使用性能服务器(服务器,服务器,内存,磁盘)并打开APC PHP来处理脚本要慢得多:)生成脚本有时只需要70毫秒,而另一个时间只是网络需要时间,从10毫秒到150毫秒不等。用户服务器。

因此,如果您想要快150毫秒,使缓冲变慢,因为需要额外的收集缓冲数据,因此会产生额外的费用。10年前,服务器制作1s脚本非常有用。

请注意output_buffering有限制,如果您想使用jpg加载它可以刷新自动化并崩溃发送。

干杯。

您可以快速上河,也可以安全地进行多摩:)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.