php 中的 ob_start() 有什么用?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4401949/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What's the use of ob_start() in php?
提问by Aditya Shukla
Is ob_start()
used for output buffering
so that the headers are buffered and not sent to the browser? Am I making sense here? If not then why should we use ob_start()
?
是ob_start()
用于output buffering
使头被缓冲,而不是发送到浏览器?我在这里有意义吗?如果不是那么我们为什么要使用ob_start()
?
回答by Riley Dutton
Think of ob_start()
as saying "Start remembering everything that would normally be outputted, but don't quite do anything with it yet."
想想ob_start()
说“开始记住通常会输出的所有内容,但还没有对它做任何事情。”
For example:
例如:
ob_start();
echo("Hello there!"); //would normally get printed to the screen/output to browser
$output = ob_get_contents();
ob_end_clean();
There are two other functions you typically pair it with: ob_get_contents()
, which basically gives you whatever has been "saved" to the buffer since it was turned on with ob_start()
, and then ob_end_clean()
or ob_flush()
, which either stops saving things and discards whatever was saved, or stops saving and outputs it all at once, respectively.
您通常将其他两个函数与它配对:ob_get_contents()
,它基本上为您提供自使用ob_start()
, 然后ob_end_clean()
或开启以来已“保存”到缓冲区的任何内容,然后或ob_flush()
,它要么停止保存内容并丢弃已保存的内容,要么停止保存并分别一次性输出。
回答by JD Isaacks
I use this so I can break out of PHP with a lot of HTML but not render it. It saves me from storing it as a string which disables IDE color-coding.
我使用它,所以我可以用大量的 HTML 突破 PHP,但不渲染它。它使我免于将其存储为禁用 IDE 颜色编码的字符串。
<?php
ob_start();
?>
<div>
<span>text</span>
<a href="#">link</a>
</div>
<?php
$content = ob_get_clean();
?>
Instead of:
代替:
<?php
$content = '<div>
<span>text</span>
<a href="#">link</a>
</div>';
?>
回答by symcbean
The accepted answer here describes what ob_start()
does - not why it is used (which was the question asked).
此处接受的答案描述了什么ob_start()
- 而不是为什么使用它(这是问的问题)。
As stated elsewhere ob_start()
creates a buffer which output is written to.
如别处所述,ob_start()
创建一个缓冲区,将输出写入其中。
But nobody has mentioned that it is possible to stack multiple buffers within PHP. See ob_get_level().
但是没有人提到可以在 PHP 中堆叠多个缓冲区。见ob_get_level()。
As to the why....
至于为什么....
Sending HTML to the browser in larger chunks gives a performance benefit from a reduced network overhead.
Passing the data out of PHP in larger chunks gives a performance and capacity benefit by reducing the number of context switches required
Passing larger chunks of data to mod_gzip/mod_deflate gives a performance benefit in that the compression can be more efficient.
buffering the output means that you can still manipulate the HTTP headers later in the code
explicitly flushingthe buffer after outputting the [head]....[/head] can allow the browser to begin marshaling other resources for the page before HTML stream completes.
Capturing the output in a buffer means that it can redirected to other functions such as email, or copied to a file as a cached representation of the content
以较大的块将 HTML 发送到浏览器可以通过减少网络开销来提高性能。
以更大的块将数据从 PHP 中传递出去,通过减少所需的上下文切换次数来提高性能和容量
将更大的数据块传递给 mod_gzip/mod_deflate 会带来性能优势,因为压缩效率更高。
缓冲输出意味着您仍然可以稍后在代码中操作 HTTP 标头
在输出 [head]....[/head] 之后显式刷新缓冲区可以允许浏览器在 HTML 流完成之前开始为页面编组其他资源。
在缓冲区中捕获输出意味着它可以重定向到其他功能,例如电子邮件,或复制到文件作为内容的缓存表示
回答by Craige
You have it backwards. ob_start does not buffer the headers, it buffers the content. Using ob_start
allows you to keep the content in a server-side buffer until you are ready to display it.
你把它倒过来了。ob_start 不缓冲标题,它缓冲内容。Usingob_start
允许您将内容保留在服务器端缓冲区中,直到您准备好显示它为止。
This is commonly used to so that pages can send headers 'after' they've 'sent' some content already (ie, deciding to redirect half way through rendering a page).
这通常用于使页面可以在它们已经“发送”一些内容之后“发送”标题(即,决定在呈现页面的中途重定向)。
回答by hawx
I prefer:
我更喜欢:
ob_start();
echo("Hello there!");
$output = ob_get_clean(); //Get current buffer contents and delete current output buffer
回答by dsdsdsdsd
this is to further clarify JD Isaaks answer...
这是为了进一步澄清JD Isaaks 的回答......
The problem you run into often is that you are using php to output html from many different php sources, and those sources are often, for whatever reason, outputting via different ways.
您经常遇到的问题是您使用 php 从许多不同的 php 源中输出 html,而这些源通常出于某种原因通过不同的方式输出。
Sometimes you have literal html content that you want to directly output to the browser; other times the output is being dynamically created (server-side).
有时您想直接输出到浏览器的文字 html 内容;其他时候输出是动态创建的(服务器端)。
The dynamic content is always(?) going to be a string. Now you have to combine this stringified dynamic html with any literal, direct-to-display html ... into one meaningful html node structure.
动态内容总是(?)将是一个字符串。现在,您必须将这个字符串化的动态 html 与任何文字、直接显示的 html ……组合成一个有意义的 html 节点结构。
This usually forces the developer to wrap all that direct-to-display content into a string (as JD Isaak was discussing) so that it can be properly delivered/inserted in conjunction with the dynamic html ... even though you don't really want it wrapped.
这通常会迫使开发人员将所有直接显示的内容包装到一个字符串中(正如 JD Isaak 所讨论的那样),以便它可以与动态 html 一起正确传递/插入......即使你真的没有想要它包裹起来。
But by using ob_## methods you can avoid that string-wrapping mess. The literal content is, instead, output to the buffer. Then in one easy step the entire contents of the buffer (all your literal html), is concatenated into your dynamic-html string.
但是通过使用 ob_## 方法,您可以避免字符串包装的混乱。相反,文字内容输出到缓冲区。然后在一个简单的步骤中,缓冲区的全部内容(所有文字 html)都连接到您的动态 html 字符串中。
(My example shows literal html being output to the buffer, which is then added to a html-string ... look also at JD Isaaks example to see string-wrapping-of-html).
(我的示例显示文本 html 被输出到缓冲区,然后将其添加到 html-string ...另请参阅 JD Isaaks 示例以查看 string-wrapping-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>
回答by jwueller
This function isn't just for headers. You can do a lot of interesting stuff with this. Example: You could split your page into sections and use it like this:
此功能不仅适用于标题。你可以用它做很多有趣的事情。示例:您可以将页面拆分为多个部分并像这样使用它:
$someTemplate->selectSection('header');
echo 'This is the header.';
$someTemplate->selectSection('content');
echo 'This is some content.';
You can capture the output that is generated here and add it at two totally different places in your layout.
您可以捕获此处生成的输出并将其添加到布局中的两个完全不同的位置。
回答by sudip
Following things are not mentioned in the existing answers : Buffer size configuration HTTP Header and Nesting.
现有答案中未提及以下内容:缓冲区大小配置 HTTP 标头和嵌套。
Buffer size configuration for ob_start :
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.
The above code improve server performance as PHP will send bigger chunks of data, for example, 4KB (wihout ob_start call, php will send each echo to the browser).
上面的代码提高了服务器性能,因为 PHP 将发送更大的数据块,例如 4KB(没有 ob_start 调用,php 会将每个回显发送到浏览器)。
If you start buffering without the chunk size (ie. a simple ob_start()), then the page will be sent once at the end of the script.
如果您在没有块大小的情况下开始缓冲(即简单的 ob_start()),那么页面将在脚本结束时发送一次。
Output buffering does not affect the HTTP headers, they are processed in different way. However, due to buffering you can send the headers even after the output was sent, because it is still in the buffer.
输出缓冲不影响 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
Nicely explained here : https://phpfashion.com/everything-about-output-buffering-in-php
在这里很好地解释:https: //phpfashion.com/everything-about-output-buffering-in-php
回答by KingCrunch
No, you are wrong, but the direction fits ;)
不,你错了,但方向合适;)
The Output-Buffering buffers the output of a script. Thats (in short) everthing after echo
or print
. The thing with the headers is, that they only can get sent, if they are not already sent. But HTTP says, that headers are the very first of the transmission. So if you output something for the first time (in a request) the headers are sent and you can not set any other headers.
输出缓冲缓冲脚本的输出。这就是(简而言之)echo
or之后的一切print
。标题的问题是,如果它们尚未发送,它们只能被发送。但是 HTTP 说,标头是传输的第一个。因此,如果您第一次输出某些内容(在请求中),则会发送标头并且您无法设置任何其他标头。