0

0

用PHP的ob_start;控制您的浏览器cache!

php中文网

php中文网

发布时间:2016-07-29 08:36:17

|

1080人浏览过

|

来源于php中文网

原创

【转载】原文地址:http://www.itbbs.cn/index.php?showtopic=1074
    Output Control 函数可以让你自由控制脚本中数据的输出。它非常地有用,特别是对于:当你想在数据已经输出后,再输出文件头的情况。输出控制函数不对使用 header() 或 setcookie(), 发送的文件头信息产生影响,只对那些类似于 echo() 和 PHP 代码的数据块有作用。
  我们先举一个简单的例子,让大家对Output Control有一个大致的印象:
  Example 1.
   

<span><br>    <span><?php   <br>ob_start</span><span>(); </span><span>//打开缓冲区  <br></span><span>echo </span><span>"Hellon\"; //输出  <br>header("</span><span>location</span><span>:</span><span>index</span><span>.</span><span>php</span><span>"); //把浏览器重定向到index.php  <br>ob_end_flush();//输出全部内容到浏览器  <br>?> <br>    </span></span>
  所有对header()函数有了解的人都知道,这个函数会发送一段文件头给浏览器,但是如果在使用这个函数之前已经有了任何输出(包括空输出,比如空格,回车和换行)就会提示出错。如果我们去掉第一行的ob_start(),再执行此程序,我们会发现得到了一条错误提示:"Header had all ready send by"!但是加上ob_start,就不会提示出错,原因是当打开了缓冲区,echo后面的字符不会输出到浏览器,而是保留在服务器,直到你使用flush或者ob_end_flush才会输出,所以并不会有任何文件头输出的错误!
一、 相关函数简介:
1、Flush:刷新缓冲区的内容,输出。
函数格式:flush()
说明:这个函数经常使用,效率很高。
2、ob_start :打开输出缓冲区
函数格式:void ob_start(void)
说明:当缓冲区激活时,所有来自PHP程序的非文件头信息均不会发送,而是保存在内部缓冲区。为了输出缓冲区的内容,可以使用ob_end_flush()或flush()输出缓冲区的内容。
3 、ob_get_contents :返回内部缓冲区的内容。
使用方法:string ob_get_contents(void)
说明:这个函数会返回当前缓冲区中的内容,如果输出缓冲区没有激活,则返回 FALSE 。
4、ob_get_length:返回内部缓冲区的长度。
使用方法:int ob_get_length(void)
说明:这个函数会返回当前缓冲区中的长度;和ob_get_contents一样,如果输出缓冲区没有激活。则返回 FALSE。
5、ob_end_flush :发送内部缓冲区的内容到浏览器,并且关闭输出缓冲区。
使用方法:void ob_end_flush(void)
说明:这个函数发送输出缓冲区的内容(如果有的话)。
6、ob_end_clean:删除内部缓冲区的内容,并且关闭内部缓冲区
使用方法:void ob_end_clean(void)
说明:这个函数不会输出内部缓冲区的内容而是把它删除!
7、ob_implicit_flush:打开或关闭绝对刷新
使用方法:void ob_implicit_flush ([int flag])
说明:使用过Perl的人都知道$|=x的意义,这个字符串可以打开/关闭缓冲区,而ob_implicit_flush函数也和那个一样,默认为关闭缓冲区,打开绝对输出后,每个脚本输出都直接发送到浏览器,不再需要调用 flush()  
二、深入了解:
1. 关于Flush函数:
这个函数在PHP3中就出现了,是一个效率很高的函数,他有一个非常有用的功能就是刷新browser的cache.我们举一个运行效果非常明显的例子来说明flush.
Example 2.
<span><br><span><?php   <br></span><span>for(</span><span>$i </span><span>= </span><span>1</span><span>; </span><span>$i </span><span><span>300</span><span>; </span><span>$i</span><span>++ ) print(</span><span>" "</span><span>);  <br></span><span>// 这一句话非常关键,cache的结构使得它的内容只有达到一定的大小才能从浏览器里输出  <br>// 换言之,如果cache的内容不达到一定的大小,它是不会在程序执行完毕前输出的。经  <br>// 过测试,我发现这个大小的底限是256个字符长。这意味着cache以后接收的内容都会  <br>// 源源不断的被发送出去。  <br></span><span>For(</span><span>$j </span><span>= </span><span>1</span><span>; </span><span>$j </span><span><span>20</span><span>; </span><span>$j</span><span>++) {  <br>echo </span><span>$j</span><span>.</span><span>"  <br>"</span><span>;  <br></span><span>flush</span><span>(); </span><span>//这一部会使cache新增的内容被挤出去,显示到浏览器上  <br></span><span>sleep</span><span>(</span><span>1</span><span>); </span><span>//让程序"睡"一秒钟,会让你把效果看得更清楚  <br></span><span>}  <br></span><span>?></span>  <br></span></span></span>
注:如果在程序的首部加入ob_implicit_flush()打开绝对刷新,就可以在程序中不再使用flush(),这样做的好处是:提高效率!
2. 关于ob系列函数:
我想先引用我的好朋友y10k的一个例子:
Example 3.
比如你用得到服务器和客户端的设置信息,但是这个信息会因为客户端的不同而不同,如果想要保存phpinfo()函数的输出怎么办呢?在没有缓冲区控制之前,可以说一点办法也没有,但是有了缓冲区的控制,我们可以轻松的解决:
<span><br><span><?php   <br>ob_start</span><span>(); </span><span>//打开缓冲区  <br></span><span>phpinfo</span><span>(); </span><span>//使用phpinfo函数  <br></span><span>$info</span><span>=</span><span>ob_get_contents</span><span>(); </span><span>//得到缓冲区的内容并且赋值给$info  <br></span><span>$file</span><span>=</span><span>fopen</span><span>('</span><span>info.txt</span><span>\'</span><span>,</span><span>\'</span><span>w</span><span>\'</span><span>); //打开文件info.txt  <br>fwrite($file,$info); //写入信息到info.txt  <br>fclose($file); //关闭文件info.txt  <br>?>  <br></span></span>
用以上的方法,就可以把不同用户的phpinfo信息保存下来,这在以前恐怕没有办法办到!其实上面就是将一些"过程"转化为"函数"的方法!
或许有人会问:"难道就这个样子吗?还有没有其他用途?"当然有了,比如笔者论坛的PHP 语法加亮显示就和这个有关(PHP默认的语法加亮显示函数会直接输出,不能保存结果,如果在每次调用都显示恐怕会很浪费CPU,笔者的论坛就把语法加亮函数显示的结果用控制缓冲区的方法保留了),大家如果感兴趣的话可以来看看http://www.zphp.com/bbs/!
可能现在大家对ob_start()的功能有了一定的了解,上面的一个例子看似简单,但实际上已经掌握了使用ob_start()的要点。
.使用ob_start打开browser的cache,这样可以保证cache的内容在你调用flush(),ob_end_flush()(或程序执行完毕)之前不会被输出。
.现在的你应该知道你所拥有的优势:可以在任何输出内容后面使用header,setcookie以及session,这是ob_start一个很大的特点;也可以使用ob_start的参数,在cache被写入后,然后自动运行命令,比如ob_start(\"ob_gzhandler\");而我们最常用的做法是用ob_get_contents()得到cache中的内容,然后再进行处理……
.当处理完毕后,我们可以使用各种方法输出,flush(),ob_end_flush(),以及等到程序执行完毕后的自动输出。当然,如果你用的是ob_get_contents(),那么就要你自己控制输出方式了。
来,让我们看看能用ob系列函数做些什么……
一、 静态模版技术
简介:所谓静态模版技术就是通过某种方式,使得用户在client端得到的是由PHP产生的html页面。如果这个html页面不会再被更新,那么当另外的用户再次浏览此页面时,程序将不会再调用PHP以及相关的数据库,对于某些信息量比较大的网站,例如sina,163,sohu。类似这种的技术带来的好处是非常巨大的。
我所知道的实现静态输出的有两种办法:
.通过y10k修改的phplib的一个叫template.inc.php类实现。
.使用ob系列函数实现。
对于第一种方法,因为不是这篇文章所要研究的问题,所以不再赘述。
我们现在来看一看第二种方法的具体实现:
Example 4.
<span><br><span><?php   <br>ob_start</span><span>();</span><span>//打开缓冲区  <br></span><span>?></span>  <br>php页面的全部输出  <br><span>  <br>$content </span><span>= </span><span>ob_get_contents</span><span>();</span><span>//取得php页面输出的全部内容  <br></span><span>$fp </span><span>= </span><span>fopen</span><span>(</span><span>"output00001.html"</span><span>, </span><span>"w"</span><span>); </span><span>//创建一个文件,并打开,准备写入  <br></span><span>fwrite</span><span>(</span><span>$fp</span><span>, </span><span>$content</span><span>); </span><span>//把php页面的内容全部写入output00001.html,然后……  <br></span><span>fclose</span><span>(</span><span>$fp</span><span>);  <br></span><span>?></span>  <br></span>
二、 捕捉输出
以上的Example 4.是一种最简单的情况,你还可以在写入前对$content进行操作……
你可以设法捕捉一些关键字,然后去对它进行再处理,比如Example 3.所述的PHP语法高亮显示。个人认为,这个功能是此函数最大的精华所在,它可以解决各种各样的问题,但需要你有足够的想象力……
Example 5.
<span><br><span>  <br></span><span>Function </span><span>run_code</span><span>(</span><span>$code</span><span>) {  <br>If(</span><span>$code</span><span>) {  <br></span><span>ob_start</span><span>();  <br>eval(</span><span>$code</span><span>);  <br></span><span>$contents </span><span>= </span><span>ob_get_contents</span><span>();  <br></span><span>ob_end_clean</span><span>();  <br>}else {  <br>echo </span><span>"错误!没有输出"</span><span>;  <br>exit();  <br>}  <br>return </span><span>$contents</span><span>;  <br>}  <br></span></span>
以上这个例子的用途不是很大,不过很典型$code的本身就是一个含有变量的输出页面,而这个例子用eval把$code中的变量替换,然后对输出结果再进行输出捕捉,再一次的进行处理……
Example 6. 加快传输
<span><br><span>  <br></span><span>/*  <br>** Title.........: PHP4 HTTP Compression Speeds up the Web  <br>** Version.......: 1.20  <br>** Author........: catoc   <br>** Filename......: gzdoc.php  <br>** Last changed..: 18/10/2000  <br>** Requirments...: PHP4 >= 4.0.1  <br>** PHP was configured with --with-zlib[=DIR]  <br>** Notes.........: Dynamic Content Acceleration compresses  <br>** the data transmission data on the fly  <br>** code by sun jin hu (catoc)   <br>** Most newer browsers since 1998/1999 have  <br>** been equipped to support the HTTP 1.1  <br>** standard known as \"content-encoding.\"  <br>** Essentially the browser indicates to the  <br>** server that it can accept \"content encoding\"  <br>** and if the server is capable it will then  <br>** compress the data and transmit it. The  <br>** browser decompresses it and then renders  <br>** the page.  <br>**  <br>** Modified by John Lim ([email]jlim@natsoft.com.my[/email])  <br>** based on ideas by Sandy McArthur, Jr  <br>** Usage........:  <br>** No space before the beginning of the first \'\' tag.  <br>** ------------Start of file----------  <br>** |  <br>** | include(\'gzdoc.php\');  <br>** |? >  <br>** |  <br>** |... the page ...  <br>** |  <br>** |  <br>** | gzdocout();  <br>** |? >  <br>** -------------End of file-----------  <br>*/  <br></span><span>ob_start</span><span>();  <br></span><span>ob_implicit_flush</span><span>(</span><span>0</span><span>);  <br>function </span><span>CheckCanGzip</span><span>(){  <br>global </span><span>$HTTP_ACCEPT_ENCODING</span><span>;  <br>if (</span><span>headers_sent</span><span>() || </span><span>connection_timeout</span><span>() || </span><span>connection_aborted</span><span>()){  <br>return </span><span>0</span><span>;  <br>}  <br>if (</span><span>strpos</span><span>(</span><span>$HTTP_ACCEPT_ENCODING</span><span>, '</span><span>x-gzip</span><span>\'</span><span>) !== false) return \"x-gzip\";  <br>if (strpos($HTTP_ACCEPT_ENCODING,</span><span>\'</span><span>gzip</span><span>\'</span><span>) !== false) return \"gzip\";  <br>return 0;  <br>}  <br>/* $level = compression level 0-9, 0=none, 9=max */  <br>function GzDocOut($level=1,$debug=0){  <br>$ENCODING = CheckCanGzip();  <br>if ($ENCODING){  <br>print \"n<!-- Use compress $ENCODING -->n\";  <br>$Contents = ob_get_contents();  <br>ob_end_clean();  <br>if ($debug){  <br>$s = \"<p>Not compress length: \".strlen($Contents);  <br>$s .= \"  <br>Compressed length: \".strlen(gzcompress($Contents,$level));  <br>$Contents .= $s;  <br>}  <br>header(\"Content-Encoding: $ENCODING\");  <br>print \"x1fx8bx08x00x00x00x00x00\";  <br>$Size = strlen($Contents);  <br>$Crc = crc32($Contents);  <br>$Contents = gzcompress($Contents,$level);  <br>$Contents = substr($Contents, 0, strlen($Contents) - 4);  <br>print $Contents;  <br>print pack(</p><div class="aritcle_card flexRow"> <div class="artcardd flexRow"> <a class="aritcle_card_img" href="/xiazai/js/3461" title="jQuery对话框、模态窗插件Remodal"><img src="https://img.php.cn/upload/jscode/000/120/096/5d79f6d1e3bf2529.jpg" alt="jQuery对话框、模态窗插件Remodal" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a> <div class="aritcle_card_info flexColumn"> <a href="/xiazai/js/3461" title="jQuery对话框、模态窗插件Remodal">jQuery对话框、模态窗插件Remodal</a> <p>Remodal 是一个扁平化,响应式,轻量,快速,容易定制的模态窗口插件。使用声明式状态符号和哈希(Hash)跟踪。所有现代的浏览器都支持。您可以轻松地定义为模态窗口定义背景容器(如模糊效果)。</p> </div> <a href="/xiazai/js/3461" title="jQuery对话框、模态窗插件Remodal" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a> </div> </div></span><span>\'</span><span>V</span><span>\'</span><span>,$Crc);  <br>print pack(</span><span>\'</span><span>V</span><span>\'</span><span>,$Size);  <br>exit;  <br>}else{  <br>ob_end_flush();  <br>exit;  <br>}  <br>}  <br>?>  <br></span></span>
这是catoc的一段很早以前的代码,是在weblogs.com看到的,他利用了zlib的函数,对传输的内容进行了压缩,测试表明,对于10k以上的页面,会产生效果,而且页面越大,效果越明显……

以上就介绍了 用PHP的ob_start;控制您的浏览器cache!,包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。

相关文章

PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

php

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

705

2026.02.13

微博网页版主页入口与登录指南_官方网页端快速访问方法
微博网页版主页入口与登录指南_官方网页端快速访问方法

本专题系统整理微博网页版官方入口及网页端登录方式,涵盖首页直达地址、账号登录流程与常见访问问题说明,帮助用户快速找到微博官网主页,实现便捷、安全的网页端登录与内容浏览体验。

233

2026.02.13

Flutter跨平台开发与状态管理实战
Flutter跨平台开发与状态管理实战

本专题围绕Flutter框架展开,系统讲解跨平台UI构建原理与状态管理方案。内容涵盖Widget生命周期、路由管理、Provider与Bloc状态管理模式、网络请求封装及性能优化技巧。通过实战项目演示,帮助开发者构建流畅、可维护的跨平台移动应用。

117

2026.02.13

TypeScript工程化开发与Vite构建优化实践
TypeScript工程化开发与Vite构建优化实践

本专题面向前端开发者,深入讲解 TypeScript 类型系统与大型项目结构设计方法,并结合 Vite 构建工具优化前端工程化流程。内容包括模块化设计、类型声明管理、代码分割、热更新原理以及构建性能调优。通过完整项目示例,帮助开发者提升代码可维护性与开发效率。

22

2026.02.13

Redis高可用架构与分布式缓存实战
Redis高可用架构与分布式缓存实战

本专题围绕 Redis 在高并发系统中的应用展开,系统讲解主从复制、哨兵机制、Cluster 集群模式及数据分片原理。内容涵盖缓存穿透与雪崩解决方案、分布式锁实现、热点数据优化及持久化策略。通过真实业务场景演示,帮助开发者构建高可用、可扩展的分布式缓存系统。

61

2026.02.13

c语言 数据类型
c语言 数据类型

本专题整合了c语言数据类型相关内容,阅读专题下面的文章了解更多详细内容。

30

2026.02.12

雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法
雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法

本专题系统整理雨课堂网页版官方入口及在线登录方式,涵盖账号登录流程、官方直连入口及平台访问方法说明,帮助师生用户快速进入雨课堂在线教学平台,实现便捷、高效的课程学习与教学管理体验。

15

2026.02.12

豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法
豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法

本专题汇总豆包AI官方网页版入口及在线使用方式,涵盖智能写作工具、图片生成体验入口和官网登录方法,帮助用户快速直达豆包AI平台,高效完成文本创作与AI生图任务,实现便捷智能创作体验。

669

2026.02.12

PostgreSQL性能优化与索引调优实战
PostgreSQL性能优化与索引调优实战

本专题面向后端开发与数据库工程师,深入讲解 PostgreSQL 查询优化原理与索引机制。内容包括执行计划分析、常见索引类型对比、慢查询优化策略、事务隔离级别以及高并发场景下的性能调优技巧。通过实战案例解析,帮助开发者提升数据库响应速度与系统稳定性。

58

2026.02.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP课程
PHP课程

共137课时 | 12.2万人学习

JavaScript ES5基础线上课程教学
JavaScript ES5基础线上课程教学

共6课时 | 11.3万人学习

PHP新手语法线上课程教学
PHP新手语法线上课程教学

共13课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号