<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></title> 
<link>http://jackxiang.com/index.php</link> 
<description><![CDATA[赢在IT，Playin' with IT,Focus on Killer Application,Marketing Meets Technology.]]></description> 
<language>zh-cn</language> 
<copyright><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></copyright>
<item>
<link>http://jackxiang.com/post//</link>
<title><![CDATA[剖析PHP中的输出缓冲 flush之类]]></title> 
<author>jack &lt;xdy108@126.com&gt;</author>
<category><![CDATA[WEB2.0]]></category>
<pubDate>Mon, 17 Dec 2007 06:31:38 +0000</pubDate> 
<guid>http://jackxiang.com/post//</guid> 
<description>
<![CDATA[ 
	我们先来看一段代码。<br/><br/>&lt;?php<br/>for ($i=10; $i&gt;0; $i--)<br/>{<br/>&nbsp;&nbsp;echo $i;<br/>&nbsp;&nbsp;flush();<br/>&nbsp;&nbsp;sleep(1);<br/>}<br/>?&gt;<br/><br/>按照php手册里的说法<br/><br/> &nbsp; &nbsp;该函数将当前为止程序的所有输出发送到用户的浏览器。<br/><br/>上面的这段代码，应该隔一秒钟输出一次$i。但是实际中却不一定是这样。有可能是等了10秒钟后，所有的输出同时呈现出来。<br/><br/>好，我们来改一下这段代码，改成<br/><br/>&lt;?php<br/>ob_end_clean();//修改部分<br/>for ($i=10; $i&gt;0; $i--)<br/>{<br/>&nbsp;&nbsp;echo $i;<br/>&nbsp;&nbsp;flush();<br/>&nbsp;&nbsp;sleep(1);<br/>}<br/>?&gt;<br/><br/>嘿，加了这一句ob_end_clean();,居然就OK了。实际上，我们把ob_end_clean()换成ob_end_flush()也一样OK。<br/><br/>我再来改一改。<br/><br/>&lt;?php<br/>for ($i=10; $i&gt;0; $i--)<br/>{<br/>&nbsp;&nbsp;echo $i;<br/>&nbsp;&nbsp;ob_flush();//修改部分<br/>&nbsp;&nbsp;flush();<br/>&nbsp;&nbsp;sleep(1);<br/>}<br/>?&gt;<br/><br/>运行一下，是不是发现$i也隔一秒输出一次了？这是为什么呢？<br/>别急，我们来看看php.ini。<br/><br/>打开php.ini,搜索output_buffering，我们会看到类似这样的设置 output_buffering = 4096。正如它的名字output_buffering一样，这个设置的作用就是把输出缓冲一下，缓冲大小为4096bytes.<br/><br/>在我们的第一段代码里，之所以没有按预期的输出，正是因为这个output_buffering把那些输出都缓冲了。没达到4096bytes或者脚本结束，输出是不会被发送出去的。<br/><br/>而第二段代码中的ob_end_clean()和ob_end_flush()的作用，就是终止缓冲。这样就不用等到有4096bytes的缓冲之后才被发送出去了。<br/><br/>第三段代码中，用了一句ob_flush(),它的作用就是把缓冲的数据发送出去，但是并不会终止缓冲，所以它必须在每次flush()前使用。<br/><br/>如果不想使用ob_end_clean(),ob_end_flush()和ob_flush()，我们就必须把php.ini里的 output_buffering设得足够小，例如设为0。需要注意的是，如果你打算在脚本中使用ini_set(” output_buffering”,”0″)来设置，那么请停下来吧，这种方法是不行的。因为在脚本一开始的时候，缓冲设置就已经被载入，然后缓冲就开始了。<br/><br/>可能你会问了，既然ob_flush()是把缓冲的数据发送出去，那么为什么还需要用flush()???直接用下面这段代码不行吗？？<br/><br/>&lt;?php<br/>for ($i=10; $i&gt;0; $i--)<br/>{<br/>&nbsp;&nbsp;echo $i;<br/>&nbsp;&nbsp;ob_flush();<br/>&nbsp;&nbsp;sleep(1);<br/>}<br/>?&gt;<br/><br/>请注意ob_flush()和flush()的区别。前者是把数据从PHP的缓冲中释放出来，后者是把不在缓冲中的或者说是被释放出来的数据发送到浏览器。所以当缓冲存在的时候，我们必须ob_flush()和flush()同时使用。<br/><br/>那是不是flush()在这里就是不可缺少的呢？不是的，我们还有另外一种方法，使得当有数据输出的时候，马上被发送到浏览器。下面这两段代码就是不需要使用flush()了。（当你把output_buffering设为0的时候，连ob_flush()和ob_end_clean()都不需要了）<br/><br/>&lt;?php<br/>ob_implicit_flush(true);<br/>for ($i=10; $i&gt;0; $i--)<br/>{<br/>&nbsp;&nbsp;echo $i;<br/>&nbsp;&nbsp;ob_flush();<br/>&nbsp;&nbsp;sleep(1);<br/>}<br/>?&gt;<br/><br/>&lt;?php<br/>ob_end_clean();<br/>ob_implicit_flush(true);<br/>for ($i=10; $i&gt;0; $i--)<br/>{<br/>&nbsp;&nbsp;echo $i;<br/>&nbsp;&nbsp;sleep(1);<br/>}<br/>?&gt;<br/><br/>请注意看上面的ob_implicit_flush(true)，这个函数强制每当有输出的时候，即刻把输出发送到浏览器。这样就不需要每次输出（echo）后，都用flush()来发送到浏览器了。<br/><br/>以上所诉可能在某些浏览器中不成立。因为浏览器也有自己的规则。我是用Firefox1.5,IE6,opera8.5来测试的。其中opera就不能正常输出，因为它有一个规则，就是不遇到一个HTML标签，就绝对不输出，除非到脚本结束。而FireFox和IE还算比较正常的。<br/><br/>最后附上一段非常有趣的代码,作者为PuTTYshell。在一个脚本周期里，每次输出，都会把前一次的输出覆盖掉。<br/>以下代码只在firefox下可用，其他浏览器并不支持multipart/x-mixed-replace的Content-Type.<br/><br/>&lt;?php<br/> &nbsp;header(&#039;Content-type: multipart/x-mixed-replace;boundary=endofsection&#039;);<br/> &nbsp;print &quot;&#92;n--endofsection&#92;n&quot;;<br/><br/> &nbsp;$pmt = array(&quot;-&quot;, &quot;&#92;&#92;&quot;, &quot;&#124;&quot;, &quot;/&quot; );<br/> &nbsp;for( $i = 0; $i &lt;10; $i ++ ){<br/> &nbsp; &nbsp; sleep(1);<br/> &nbsp; &nbsp; print &quot;Content-type: text/plain&#92;n&#92;n&quot;;<br/> &nbsp; &nbsp; print &quot;Part $i&#92;t&quot;.$pmt[$i % 4];<br/> &nbsp; &nbsp; print &quot;--endofsection&#92;n&quot;;<br/> &nbsp; &nbsp; ob_flush();<br/> &nbsp; &nbsp; flush();<br/> &nbsp;}<br/> &nbsp;print &quot;Content-type: text/plain&#92;n&#92;n&quot;;<br/> &nbsp;print &quot;The end&#92;n&quot;;<br/> &nbsp;print &quot;--endofsection--&#92;n&quot;;<br/>?&gt;
]]>
</description>
</item><item>
<link>http://jackxiang.com/post//#blogcomment</link>
<title><![CDATA[[评论] 剖析PHP中的输出缓冲 flush之类]]></title> 
<author> &lt;user@domain.com&gt;</author>
<category><![CDATA[评论]]></category>
<pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate> 
<guid>http://jackxiang.com/post//#blogcomment</guid> 
<description>
<![CDATA[ 
	
]]>
</description>
</item>
</channel>
</rss>