前言
一个网页的前端页面都会有部分片段是静态的,比如头部部分,页脚部分,通常他们的引用是
<?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())