前言
一个网页的前端页面都会有部分片段是静态的,比如头部部分,页脚部分,通常他们的引用是
<?php include COMMON_PATH.'/footer.html'; ?>
但是,当这些引入页面里包含php代码需要解析,并且长期不做变化的,则会消耗一定的资源,比如如下footer.html页面
所以,将它们静态化处理,是一种不错的选择手段.
我用的是Yaf框架,所以前端引用修改成为
<?php Helper::load('cache')->checkCache('footer');?>
因为框架路由调用原因,我把Cache.php封装成为了一个类
代码解读
该类下之意一个函数checkCache(),该函数注释比较清晰,所以就不多阐述了,函数代码如下:
/**判断cache文件有没有缓存,有则使用,无则先存入再使用编译
* 对视图menus.html和footer.html进行缓存处理
* @param string $name
* @return string
* 如何调用:在前端文件写入<?php Helper::load('cache')->checkCache('menus');?>
*/
public function checkCache($name=''){
//是否存在该缓存
$is_include=false;
//文件夹路径
$path= CACHE_PATH ."/";
//打开文件夹
$handle=opendir($path);
//读取文件
while(($item=readdir($handle))!==false){
//去掉.和..
if($item!="."&&$item!=".."){
//判断是否是文件
if(is_file($path.'/'.$item)){
//获得文件名
$fileName=$item;
//判断文件名是否包含该字段
$result=strpos($fileName,$name);
//如果存在
if($result!==false){
$is_include=TRUE;
$realFilePath=$path.'/'.$fileName;
}
}
}
}
//关闭权柄
closedir($handle);
//有则返回该文件内容,真实文件地址不能为空,文件内容不能为空,5分钟更新文件一次
if($is_include===TRUE&&!empty($realFilePath)&&!empty(file_get_contents($realFilePath))&&(time() - filemtime($realFilePath)) < 300){
// $oldfile = fopen("$realFilePath", "r");
// $content=fread($oldfile,filesize("$realFilePath"));
// fclose($oldfile);
// return $content;
require_once("$realFilePath");
}else{
//如果超时,先检测是否确保文件删除掉
if(!empty($realFilePath)&&(time() - filemtime($realFilePath)) >= 300){
unlink($realFilePath);
}
//没有就按照{$name}.txt存储,返回编译文件内容
$newname=$name.'.html';//新的文件名
$newPath=$path.$newname;//存放的路径
ob_start(); // 开始输入缓冲
include COMMON_PATH."/$name.html";
file_put_contents($newPath, ob_get_flush());//获取缓冲区内容并写入文件
//$content=file_get_contents($newPath);//把文件读出到一个字符串
//return $content;
}
}
就这样,我们把页面做了最简单的静态化缓存
在写这个缓存类的时候,刚开始想到使用用文件创建/打开/读取,但是heredoc语法结构:
在代码中可以解析变量,不能解析函数
$str= <<<EOT
<?php include COMMON_PATH.'/footer.html'; ?>
EOT;
如上存入文件就是原样存入文件,那么我希望代码解析之后在存入文件,那么怎么做呢?这时候,php的缓冲区ob系列函数拯救了我
截取代码的片段:
//没有就按照{$name}.txt存储,返回编译文件内容
$newname=$name.'.html';//新的文件名
$newPath=$path.$newname;//存放的路径
ob_start(); // 开始输入缓冲
include COMMON_PATH."/$name.html";
file_put_contents($newPath, ob_get_flush());//获取缓冲区内容并写入文件
总结
下面对OB系列函数进行一定的整理:
flush()
-刷新缓冲区的内容输出
ob_start()
- 打开输出控制缓冲(当缓冲区激活时,所有来自PHP程序的非文件头信息均不会发送,而是保存在内部缓冲区。为了输出缓冲区的内容,可以使用ob_end_flush()或flush()输出缓冲区的内容)
ob_get_length()
-返回输出缓冲区的长度(这个函数会返回当前缓冲区中的长度;和ob_get_contents一样,如果输出缓冲区没有激活。则返回 FALSE)
ob_get_level()
-返回输出缓冲区的嵌套级别
ob_get_status()
-返回输出缓冲区的状态(数组形式返回,默认返回最顶层,参数为true时返回所有)
ob_get_contents()
-返回输出缓冲区的内容(这个函数会返回当前缓冲区中的内容,如果输出缓冲区没有激活,则返回 FALSE)
ob_get_clean()
-以字符串格式返回当前输出缓冲区并关闭输出缓冲(图片处理时常用)
ob_end_clean()
-清空(擦除)缓冲区并关闭输出缓冲(这个函数不会输出内部缓冲区的内容而是把它删除)
ob_get_flush()
-以字符串返回输出缓冲区内容并关闭缓冲
ob_end_flush()
-冲刷出(送出)输出缓冲区内容缓冲
ob_implicit_flush()
-打开或关闭绝对刷新(使用过Perl的人都知道$|=x的意义,这个字符串可以打开/关闭缓冲区,而ob_implicit_flush函数也和那个一样,默认为关闭缓冲区,打开绝对输出后,每个脚本输出都直接发送到浏览器,不再需要调用 flush())