远程控制客户端:PHP来控制客户端cache
来源: 发布时间:星期四, 2009年2月12日 浏览:55次 评论:0
Output Control 可以让你自由控制脚本中数据输出它非常地有用特别是对于:当你想在数据已经输出后再输出文件头情况输出控制不对使用 header 或 cookie, 发送文件头信息产生影响,只对那些类似于 echo 和 PHP 代码数据块有作用
我们先举个简单例子让大家对Output Control有个大致印象:
Example 1.
<?php
ob_start; //打开缓冲区
echo \"Hellon\"; //输出
header(“location:index.php”); //把浏览器重定向到index.php
ob_end_flush;//输出全部内容到浏览器
?>
所有对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 :返回内部缓冲区内容
使用思路方法: ob_get_contents(void)
介绍说明:这个会返回当前缓冲区中内容如果输出缓冲区没有激活则返回 FALSE
4、ob_get_length:返回内部缓冲区长度
使用思路方法: 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 ([ flag])
介绍说明:使用过Perl人都知道$|=x意义这个串可以打开/关闭缓冲区而ob_implicit_flush也和那个样默认为关闭缓冲区打开绝对输出后每个脚本输出都直接发送到浏览器不再需要 flush
2、深入了解:
1. 有关Flush:
这个在PHP3中就出现了是个效率很高他有个非常有用功能就是刷新browsercache.我们举个运行效果非常明显例子来介绍说明flush.
Example 2.
<?php
for($i = 1; $i <= 300; $i ) pr(“ “);
// 这句话非常关键cache结构使得它内容只有达到定大小才能从浏览器里输出
// 换言的如果cache内容不达到定大小它是不会在执行完毕前输出经
// 过测试我发现这个大小底限是256个长这意味着cache以后接收内容都会
// 源源不断被发送出去
For($j = 1; $j <= 20; $j) {
echo $j.”
”;
flush; //这部会使cache新增内容被挤出去显示到浏览器上
sleep(1); //让“睡”秒钟会让你把效果看得更清楚
}
?>
具体效果你可以到这里看看http://www.php2000.com/~uchinaboy/out.php
PHP2000最新PHP聊天室就是用这个技术可惜是源代码未公开 L
注:如果在首部加入ob_implicit_flush打开绝对刷新,就可以在中不再使用flush,这样做好处是:提高效率!
2. 有关ob系列:
我想先引用我好朋友y10k个例子:
Example 3.
比如你用得到服务器和客户端设置信息但是这个信息会客户端区别而区别如果想要保存phpinfo输出如何办呢?在没有缓冲区控制的前可以说点办法也没有但是有了缓冲区控制我们可以轻松解决:
<?php
ob_start; //打开缓冲区
phpinfo; //使用phpinfo
$info=ob_get_contents; //得到缓冲区内容并且赋值给$info
$file=fopen(\'info.txt\',\'w\'); //打开文件info.txt
fwrite($file,$info); //写入信息到info.txt
fclose($file); //关闭文件info.txt
?>
用以上思路方法就可以把区别用户phpinfo信息保存下来这在以前恐怕没有办法办到!其实上面就是将些“过程”转化为“”思路方法!
或许有人会问:“难道就这个样子吗?还有没有其他用途?”当然有了比如笔者论坛PHP 语法加亮显示就和这个有关(PHP默认语法加亮显示会直接输出不能保存结果如果在每次都显示恐怕会很浪费CPU笔者论坛就把语法加亮显示结果用控制缓冲区思路方法保留了)大家如果感兴趣话可以来看看http://www.zphp.com/bbs/!
可能现在大家对ob_start功能有了定了解上面个例子看似简单但实际上已经掌握了使用ob_start要点
<1>.使用ob_start打开browsercache这样可以保证cache内容在你flush,ob_end_flush(或执行完毕)的前不会被输出
<2>.现在你应该知道你所拥有优势:可以在任何输出内容后面使用header,cookie以及session这是ob_start个很大特点;也可以使用ob_start参数在cache被写入后然后自动运行命令比如ob_start(\"ob_gzhandler\");而我们最常用做法是用ob_get_contents得到cache中内容然后再进行处理……
<3>.当处理完毕后我们可以使用各种思路方法输出flush,ob_end_flush,以及等到执行完毕后自动输出当然如果你用是ob_get_contents那么就要你自己控制输出方式了
来让我们看看能用ob系列做些什么……
、 静态模版技术
介绍:所谓静态模版技术就是通过某种方式使得用户在client端得到是由PHP产生html页面如果这个html页面不会再被更新那么当另外用户再次浏览此页面时将不会再PHP以及相关数据库对于某些信息量比较大网站WebSite例如sina,163,sohu类似这种技术带来好处是非常巨大
我所知道实现静态输出有两种办法:
<1>.通过y10k修改phplib个叫template.inc.php类实现
<2>.使用ob系列实现
对于第种思路方法不是这篇文章所要研究问题所以不再赘述
我们现在来看看第 2种思路方法具体实现:
Example 4.
<?php
ob_start;//打开缓冲区
?>
php页面全部输出
<?
$content = ob_get_contents;//取得php页面输出全部内容
$fp = fopen(“output00001.html”, “w”); //创建个文件并打开准备写入
fwrite($fp, $content); //把php页面内容全部写入output00001.html然后……
fclose($fp);
?>
这样所谓静态模版就很容易被实现了……
2、 捕捉输出
以上Example 4.是种最简单情况你还可以在写入前对$content进行操作……
你可以设法捕捉些关键字然后去对它进行再处理比如Example 3.所述PHP语法高亮显示个人认为这个功能是此最大精华所在它可以解决各种各样问题但需要你有足够想象力……
Example 5.
<?
Function run_code($code) {
If($code) {
ob_start;
eval($code);
$contents = ob_get_contents;
ob_end_clean;
} {
echo “!没有输出”;
exit;
}
$contents;
}
以上这个例子用途不是很大不过很典型$code本身就是个含有变量输出页面而这个例子用eval把$code中变量替换然后对输出结果再进行输出捕捉再次进行处理……
Example 6. 加快传输
<?
/*
** Title.........: PHP4 HTTP Compression Speeds up the Web
** Version.......: 1.20
** Author........: catoc <catoc@163.net>
** Filename......: gzdoc.php
** Last changed..: 18/10/2000
** Requirments...: PHP4 >= 4.0.1
** PHP was configured with --with-zlib[=DIR]
** Notes.........: Dynamic Content Acceleration compresses
** the data transmission data _disibledevent=> (strpos($HTTP_ACCEPT_ENCODING,\'gzip\') ! false) \"gzip\";
0;
}
/* $level = compression level 0-9, 0=none, 9=max */
function GzDocOut($level=1,$debug=0){
$ENCODING = CheckCanGzip;
($ENCODING){
pr \"n<!-- Use compress $ENCODING -->n\";
$Contents = ob_get_contents;
ob_end_clean;
($debug){
$s = \"<p>Not compress length: \".strlen($Contents);
$s .= \"
Compressed length: \".strlen(gzcompress($Contents,$level));
$Contents .= $s;
}
header(\"Content-Encoding: $ENCODING\");
pr \"x1fx8bx08x00x00x00x00x00\";
$Size = strlen($Contents);
$Crc = crc32($Contents);
$Contents = gzcompress($Contents,$level);
$Contents = substr($Contents, 0, strlen($Contents) - 4);
pr $Contents;
pr pack(\'V\',$Crc);
pr pack(\'V\',$Size);
exit;
}{
ob_end_flush;
exit;
}
}
?>
这是catoc段很早以前代码是在weblogs.com看到他利用了zlib对传输内容进行了压缩测试表明对于10k以上页面会产生效果而且页面越大效果越明显…