在php中ob_start()的使用是什么?

ob_start()是否用于output buffering,以便头文件被缓冲而不发送到浏览器?我说的有道理吗?如果不是,那么为什么我们要使用ob_start()?

347289 次浏览

这个函数不仅仅用于头文件。你可以用它做很多有趣的事情。例子:你可以把你的页面分成几个部分,像这样使用:

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


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

您可以捕获此处生成的输出,并将其添加到布局中的两个完全不同的位置。

你搞反了。Ob_start不缓冲头文件,它缓冲内容。使用ob_start允许您将内容保存在服务器端缓冲区中,直到您准备好显示它。

这是常用的,这样页面就可以在他们已经“发送”了一些内容之后发送标题(例如,在渲染页面的中途决定重定向)。

不,你错了,但方向是合适的;)

output - buffering缓冲脚本的输出。这(简而言之)是echoprint之后的所有内容。头部的事情是,他们只能被发送,如果他们还没有被发送。但是HTTP表示,头信息是传输的第一步。因此,如果你第一次(在请求中)输出某些内容,则发送头信息,并且不能设置其他头信息。

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

这是为了进一步澄清艾萨克的回答

您经常遇到的问题是,您使用php从许多不同的php源输出html,而出于某种原因,这些源通常通过不同的方式输出。

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

动态内容总是一个字符串。现在你必须结合这个字符串化的动态html与任何文字,直接显示html…转换成一个有意义的HTML节点结构。

这通常迫使开发人员将所有直接显示的内容包装成一个字符串(就像JD Isaak讨论的那样),这样它就可以与动态html一起正确地交付/插入……即使你不想把它包起来。

但是通过使用ob_##方法,可以避免字符串换行的混乱。相反,文字内容输出到缓冲区。然后在一个简单的步骤,整个内容的缓冲区(所有文字html),连接到您的动态html字符串。

(我的例子显示文字html输出到缓冲区,然后添加到一个html-string…也可以看看JD Isaaks的例子,看看字符串- wrapped -of-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. 显式flush 缓冲后输出[head]....[/head]可以允许浏览器在HTML流完成之前开始为页面编组其他资源。

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

我喜欢:

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

以下内容在现有的答案中没有提到: 缓冲区大小配置 HTTP报头 和嵌套。< / p >

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