首页 > 代码库 > PHP中输出缓冲
PHP中输出缓冲
在PHP中,当执行echo,print的时候,输出并没有立即通过tcp传给客户端浏览器显示, 而是将数据写入php buffer。php output_buffering机制,意味在tcp buffer之前,建立了一新的队列,数据必须经过该队列。当一个php buffer写满的时候,脚本进程会将php buffer中的输出数据交给系统内核交由tcp传给浏览器显示。所以,数据会依次写到这几个地方echo/pring -> php buffer -> tcp buffer -> browser
在PHP中与刷新缓冲相关的函数有三个:
1). flush
刷新PHP程序的缓冲,而不论PHP执行在何种情况下。该函数将当前为止程序的所有输出发送到用户的浏览器。 但是该函数不会对服务器或客户端浏览器的缓存模式产生任何影响,也不会对PHP本身的缓存产生任何影响。
2).ob_flush
该函数对PHP本身的的缓存进行输出。PHP本身的缓存受php.ini中的output_buffering的控制。ob_flush()的作用就是将本来存在输出缓存中的内容取出来,设置为等待输出状态,但不会直接发送到客户端,这时你就需要先使用ob_flush()再使用flush(),客户端才能立即获得脚本的输出。
3).ob_implicit_flush
这个函数强制每当有输出的时候,即刻把输出发送到浏览器。这样就不需要每次输出(echo)后,都用flush()来发送到浏览器了。
例子
- <?php
- ob_end_clean();
- echo
str_pad(" " ,256); - for
( $i=100;$i>0; $i--) { -
echo $i, ‘<br/>‘; -
flush(); -
sleep(1); - }
- ?>
- <?php
- echo
str_pad(" " ,256); - for
( $i=100;$i>0; $i--) { -
echo $i, ‘<br />‘ ; -
ob_flush(); //有时候只有flush是不行的 -
flush(); -
sleep(1); - }
- ?>
- <?php
- ob_implicit_flush(true);
- echo
str_pad(" " ,256); - for
( $i=100;$i>0; $i--) { -
echo $i, ‘<br />‘ ; -
ob_flush(); -
sleep(1); - }
- ?>
另外我们还需要注意刷新缓冲不光受以上几方面的影响,还受以下影响:
1). 个别web服务器程序,特别是Win32下的web服务器程序,在发送结果到浏览器之前,仍然会缓存脚本的输出,直到程序结束为止。有些Apache的模块,比如mod_gzip,可能自己进行输出缓存,这将导致flush()函 数产生的结果不会立即被发送到客户端浏览器。甚至浏览器也会在显示之前,缓存接收到的内容。例如 Netscape 浏览器会在接受到换行或 html 标记的开头之前缓存内容,并且在接受到 </table> 标记之前,不会显示出整个表格。一些版本的 Microsoft Internet Explorer 只有当接受到的256个字节以后才开始显示该页面,所以必须发送一些额外的空格来让这些浏览器显示页面内容。
下面是很简单的一段代码
<?php /*--------------------编写自己的缓存类---------------*/ class my_cache{ //定义有关变量 private $cache_time;//缓存有效时间 private $cache_file;//缓存文件保存路径 //初始化类,默认是index.html时间是1 function __construct($cache_file='index.html',$cache_time="1"){ $this->cache_file=$cache_file; $this->cache_time=$cache_time; } //缓存开始 function cache_start(){ if ($this->cache_active){ include($this->cache_file); exit; } //开启缓存 ob_start(); } //判断缓存文件是否存在并且可用 function cache_active(){ //判断文件是否存在 if(file_exists($this->cache_file)){ $last_time=@filemtime($this->cache_file);//获取最后修改时间 //判断时间是否可用 if($this->cache_time<$last_time){ //可用,包含进来直接显示 return true; }else{ //删除该缓存,重新建立缓存 unlink($this->cache_file); return false; } } } //进行缓存目录的生成 function cache_creat(){ //不用判断直接生成缓存文件目录及文件,循环生成文件 $file=explode("/", $this->cache_file); $num=count($file)-1; for ($i=0;$i<$num;$i++){ $tm.=$file[$i]."/"; if (!file_exists($tm)){ mkdir($tm); } } } //缓存的输出 function cache_end(){ $cache_content=ob_get_contents(); $this->cache_creat(); $fp=@fopen($this->cache_file, "w+"); fwrite($fp, $cache_content); ob_end_flush(); } //缓存的清除 function cache_clean(){ if(unlink($this->cache_file)){ return true; }else { $this->alert("缓存删除失败!请检查缓存文件是否存在"); return false; } } //定义缓存文件的提醒函数 function alert($a){ echo "<script>alert('$a');</script>"; } } ?> 测试页面test.php <? include 'cache_my_class.php'; $my_cache=new my_cache("./chunge/ge/hao/index.html",5); $my_cache->cache_start(); //在页面的最开始 -------页面输出 $like="我爱吃橘子香蕉!"; echo $like."<br>"; $my_cache->cache_end();//最后进行输出