在php中有什么用ob_start()?

问题描述:

ob_start()用于output buffering这样标题被缓冲而不发送到浏览器?我在这里有意义吗?如果不是,那我们为什么要用ob_start()在php中有什么用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(),它们要么停止保存东西并丢弃所保存的内容,要么分别停止保存并一次输出。

+33

很好的解释。我会更进一步,并用`ob_get_clean()`替换`ob_get_contents()`,并移除`ob_end_clean()`,因为`ob_get_clean()`实质上执行了两个函数。参考:http://php.net/manual/en/function.ob-get-clean.php(PHP 4> = 4.3.0,PHP 5) – 2015-05-20 16:49:22

+0

我假设输出缓冲必须以.ini文件顺序启用调用`ob_start();`这是正确的吗?如果未启用会发生什么情况? – 2015-08-14 03:48:00

此函数不仅用于标题。你可以用这个做很多有趣的事情。例如:你可以分割你的网页到段,并使用它像这样:

$someTemplate->selectSection('header'); 
echo 'This is the header.'; 

$someTemplate->selectSection('content'); 
echo 'This is some content.'; 

您可以捕捉在这里生成的输出,并在布局两个完全不同的地方添加它。

+0

这种看起来像我在找的东西。我需要渲染'部分'的东西(想到JS和CSS文件),但我需要能够在模板中调用它们(它比标题稍晚加载)...所以如果我调用“$ this - > addcss( 'specificCSStoThisView');”我希望它在

标签之间进行渲染。但是,我似乎无法谷歌这一点。你能否指点我正确的方向?谢谢! – NoobishPro 2015-12-05 01:01:24

你有它向后。 ob_start不缓冲标题,它缓冲内容。使用ob_start可让您将内容保留在服务器端缓冲区中,直到您准备好显示它为止。

这是常用的,以便页面可以在'已经'发送'一些内容之后发送头'(即,决定通过渲染页面中途重定向)。

+3

+1我也对这个函数的实际用法感到困惑。您在“重定向”期间对其使用的回答让我想起了所有的时间,我有错误“Headers already sent”。谢谢 – pat 2014-02-02 19:40:37

不,你错了,但方向符合;)

输出缓冲缓冲的脚本的输出。那(简而言之)echoprint之后。标题是,他们只能发送,如果他们还没有发送。但HTTP表示,标题是传输的第一个。所以如果你第一次输出的东西(在请求中)头部被发送,你不能设置任何其他头部。

我使用这个,所以我可以用大量的HTML来打破PHP但不能呈现它。它使我无法将其存储为禁用颜色编码的字符串。

<?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>'; 
?> 

这是进一步明确JD Isaaks答案...

你遇到经常的问题是,你正在使用PHP输出HTML从许多不同的PHP的资源,而且这些资源往往是出于任何原因通过不同的方式输出。

有时你有直接输出到浏览器的文字html内容;其他时间输出是动态创建的(服务器端)。

动态内容始终是(?)将是一个字符串。现在你必须将这个字符串化的动态html与任何直接显示html的文字结合成一个有意义的html节点结构。

这通常会迫使开发人员将所有直接显示内容封装到字符串中(如JD Isaak所讨论的),以便它可以与动态html一起正确传递/插入......即使您不是真的想要它包裹。

但通过使用ob _ ##方法,您可以避免该字符串包装混乱。而文字内容则输出到缓冲区。然后在一个简单的步骤中将缓冲区的全部内容(所有文字html)连接到您的dynamic-html字符串中。 (我的例子显示输出到缓冲区的文字html,然后将其添加到html字符串中...另请参阅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> 

这里接受的答案描述了ob_start()那样 - 为什么不使用它(这是问的问题)。

如其他地方所述ob_start()创建输出写入的缓冲区。

但没有人提到可以在PHP中堆叠多个缓冲区。请参阅ob_get_level()。

至于为什么....

  1. 较大的块发送HTML浏览器给出了降低网络开销性能优势。

  2. 在较大的块传递的数据从PHP的通过降低上下文的开关需要

  3. 传递较大的数据到MOD_GZIP的组块的数目给出了一个性能和容量的益处/ mod_deflate模块给出,所述压缩性能益处可以更有效率。

  4. 缓冲输出意味着可以仍然以后操纵的HTTP标头中的代码

  5. 明确输出[头]后在缓冲冲洗 .... [/头]可以允许浏览器在HTML流完成之前开始封送页面的其他资源。

  6. 捕获在缓冲器中输出意味着它可以重定向到其它功能,例如电子邮件,或复制文件,作为所述内容的缓存表示

我更喜欢:

ob_start(); 
echo("Hello there!"); 
$output = ob_get_clean(); //Get current buffer contents and delete current output buffer