ob_start()
用于output buffering
,以便标头被缓冲而不发送到浏览器吗?我在这里有道理吗?如果没有那么我们为什么要使用ob_start()
?
想想ob_start()
说“开始记住通常会输出的所有东西,但还没有对它做任何事情。”
例如:
ob_start();
echo("Hello there!"); //would normally get printed to the screen/output to browser
$output = ob_get_contents();
ob_end_clean();
还有另外两个你通常配对的函数:ob_get_contents()
,它基本上为你提供了什么已被“保存”到缓冲区,因为它是用ob_start()
打开的,然后是ob_end_clean()
或ob_flush()
,它们会停止保存并丢弃保存的内容,或分别停止保存并一次性输出。
我使用这个,所以我可以用很多HTML打破PHP,但不能渲染它。它使我无法将其存储为禁用IDE颜色编码的字符串。
<?php
ob_start();
?>
<div>
<span>text</span>
<a href="#">link</a>
</div>
<?php
$content = ob_get_clean();
?>
代替:
<?php
$content = '<div>
<span>text</span>
<a href="#">link</a>
</div>';
?>
这里接受的答案描述了ob_start()
的作用 - 不是为什么使用它(这是问题)。
正如其他地方所述,ob_start()
创建了一个写入输出的缓冲区。
但是没有人提到可以在PHP中堆叠多个缓冲区。见ob_get_level()。
至于为什么....
你倒退了。 ob_start不缓冲标头,它缓冲内容。使用ob_start
可以将内容保留在服务器端缓冲区中,直到您准备好显示它为止。
这通常用于使页面可以在“已经''已经'发送'一些内容之后发送标题(即,决定通过呈现页面的一半重定向)。
我更喜欢:
ob_start();
echo("Hello there!");
$output = ob_get_clean(); //Get current buffer contents and delete current output buffer
这是为了进一步澄清JD Isaaks answer ......
你经常遇到的问题是你使用php从许多不同的php源输出html,并且这些源通常无论出于什么原因通过不同的方式输出。
有时你想要直接输出到浏览器的文字html内容;其他时候输出是动态创建的(服务器端)。
动态内容总是(?)将成为一个字符串。现在你必须将这个字符串化的动态html与任何文字的,直接显示的html ...组合成一个有意义的html节点结构。
这通常会迫使开发人员将所有直接显示内容包装成一个字符串(正如JD Isaak所讨论的那样),这样它就可以与动态html一起正确地传递/插入......即使你不是真的希望它包裹起来。
但是通过使用ob _ ##方法,你可以避免那个字符串包装混乱。相反,文字内容输出到缓冲区。然后在一个简单的步骤中,缓冲区的所有内容(所有文字html)将连接到您的dynamic-html字符串中。
(我的例子显示了将文字html输出到缓冲区,然后将其添加到html-string中......另请参阅JD Isaaks示例以查看字符串包装的html)。
<?php // parent.php
//---------------------------------
$lvs_html = "" ;
$lvs_html .= "<div>html</div>" ;
$lvs_html .= gf_component_assembler__without_ob( ) ;
$lvs_html .= "<div>more html</div>" ;
$lvs_html .= "----<br/>" ;
$lvs_html .= "<div>html</div>" ;
$lvs_html .= gf_component_assembler__with_ob( ) ;
$lvs_html .= "<div>more html</div>" ;
echo $lvs_html ;
// 02 - component contents
// html
// 01 - component header
// 03 - component footer
// more html
// ----
// html
// 01 - component header
// 02 - component contents
// 03 - component footer
// more html
//---------------------------------
function gf_component_assembler__without_ob( )
{
$lvs_html = "<div>01 - component header</div>" ; // <table ><tr>" ;
include( "component_contents.php" ) ;
$lvs_html .= "<div>03 - component footer</div>" ; // </tr></table>" ;
return $lvs_html ;
} ;
//---------------------------------
function gf_component_assembler__with_ob( )
{
$lvs_html = "<div>01 - component header</div>" ; // <table ><tr>" ;
ob_start();
include( "component_contents.php" ) ;
$lvs_html .= ob_get_clean();
$lvs_html .= "<div>03 - component footer</div>" ; // </tr></table>" ;
return $lvs_html ;
} ;
//---------------------------------
?>
<!-- component_contents.php -->
<div>
02 - component contents
</div>
此功能不仅适用于标题。你可以用这个做很多有趣的事情。示例:您可以将页面拆分为多个部分并按如下方式使用:
$someTemplate->selectSection('header');
echo 'This is the header.';
$someTemplate->selectSection('content');
echo 'This is some content.';
您可以捕获此处生成的输出,并将其添加到布局中两个完全不同的位置。
不,你错了,但方向适合;)
输出缓冲缓冲脚本的输出。多数民众赞成在echo
或print
之后。带标题的是,如果它们尚未发送,它们只能被发送。但HTTP说,标头是传输中的第一个。因此,如果您第一次输出内容(在请求中),则会发送标头,您无法设置任何其他标头。
现有答案中未提及以下内容:缓冲区大小配置HTTP标头和嵌套。
ob_start的缓冲区大小配置:
ob_start(null, 4096); // Once the buffer size exceeds 4096 bytes, PHP automatically executes flush, ie. the buffer is emptied and sent out.
上面的代码提高了服务器性能,因为PHP将发送更大的数据块,例如4KB(没有ob_start调用,php会将每个echo发送到浏览器)。
如果您在没有块大小的情况下开始缓冲(即简单的ob_start()),那么页面将在脚本结束时发送一次。
输出缓冲不会影响HTTP标头,它们以不同的方式处理。但是,由于缓冲,您甚至可以在发送输出后发送标头,因为它仍然在缓冲区中。
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
在这里很好地解释:https://phpfashion.com/everything-about-output-buffering-in-php