当我使用不带ob_end_clean()或ob_end_flush()的多ob_start()时发生了什么?

时间:2012-05-04 01:08:09

标签: php output-buffering

我已经查看了关于ob_start()ob_end_clean()ob_end_flush()的php手册。我已经看到了关于这个主题的一个不同的例子,无论如何我修改了这个例子但是我在这一点上感到困惑。这是脚本。

ob_start();
echo "Hello x, ";

ob_start();
echo "Hello y, ";

ob_start();
echo "Hello z, ";

ob_start();
echo "Hello World";
$ob_2 = ob_get_contents();
ob_end_clean();

echo "Galaxy";
$ob_1 = ob_get_contents();
ob_end_clean();

echo " this is OB_1 : ".$ob_1;
echo "<br>  and this is OB_2  : ".$ob_2;

此脚本的输出是:

你好x,你好y,这是OB_1:你好z,Galaxy

,这是OB_2:Hello World

--------------------------------------------

为什么输出不是那样的?

这是OB_1:Hello x,Hello y,Hello z,Galaxy

,这是OB_2:Hello World

我错过了什么?

2 个答案:

答案 0 :(得分:33)

我会注释你的代码来解释发生了什么。所有输出缓冲区都初始化为空,这是标准的:

ob_start(); // open output buffer 1
echo "Hello x, "; // echo appended to output buffer 1

ob_start(); // open output buffer 2
echo "Hello y, "; // echo appended output buffer 2

ob_start(); // open output buffer 3
echo "Hello z, "; // echo appended to output buffer 3

ob_start(); // open output buffer 4
echo "Hello World"; // echo appended output buffer 4
$ob_2 = ob_get_contents(); // get contents of output buffer 4
ob_end_clean(); // close and throw away contents of output buffer 4

echo "Galaxy"; // echo appended to output buffer 3
$ob_1 = ob_get_contents(); // get contents of output buffer 3
ob_end_clean(); // close and throw away contents of output buffer 3

// at this point, $ob_2 = "Hello World" and $ob_1 = "Hello z, Galaxy"
// output buffer 1 = "Hello x," and output buffer 2 = "Hello y,"

echo " this is OB_1 : ".$ob_1; // echo appended to output buffer 2

// output buffer 2 now looks like "Hello y,  this is OB_1 : Hello z, Galaxy" 

echo "<br>  and this is OB_2  : ".$ob_2; // echo appended to output buffer 2

// output buffer 2 now looks like:
//   "Hello y,  this is OB_1 : Hello z, Galaxy<br> and this is OB_2  : Hello World"

// output buffer 2 implicitly flushed by end of script
// output from buffer 2 captured by (appended to) output buffer 1
// output buffer 1 now looks like:
//   "Hello x, Hello y,  this is OB_1 : Hello z, Galaxy<br> and this is OB_2  : Hello World"
// output buffer 1 implicitly closed by end of script. This is when your output
// actually gets printed for this particular script.

答案 1 :(得分:18)

输出缓冲区就像堆栈一样工作。你创建一个缓冲区并回显“Hello x”,然后创建另一个缓冲区并在其中回显“Hello y”,然后创建第三个缓冲区并回显“Hello z”。 “Hello World”进入第四个缓冲区,通过调用ob_end_clean()关闭,所以你回到了第三个缓冲区。在回显“Galaxy”后调用ob_get_contents()时,您将获得该第三个缓冲区的内容。

如果您在此代码的末尾再次调用ob_get_contents(),您将获得第二个缓冲区中的“Hello y”。如果您ob_end_close()再次ob_get_contents(),那么您将从第一个缓冲区获得“Hello x”。