文件缓存就是指把缓存数据存储到文件系统也就是硬盘中,大家都知道与内存相比,硬盘是属于速度比较慢的存储设备,为什么我们要使用这个呢???
原因很简单,磁盘容量大,可以存放足够多的数据,现在常规的硬盘已经进入到了TB级别,而内存还处于GB级别,并且呢,磁盘的价格远远低于内存,它还比内存更加的稳定和可靠,最起码断电后数据不会丢失,存储也是比较简单,还有就是固态硬盘的出现,使得硬盘的读写速度得到了极大的提升,最后就是扩展方面了,我们可以使用磁盘阵列、分布式处理等进行大规模的存储和管理,相比较来说,貌似确实是硬盘性价比更高些。
文件缓存机制的逻辑很清晰,模板的作用之一就是把动态的PHP动态代码编译成静态的HTML文件,当下次读取的时候不会再经过编译,我们来看一个简单的模板引擎进行文件缓存的代码实例,首先是模板类:
//Template.php
class Template{
private $arrayConfig = array(
'suffix' => '.m', //模板文件的后缀
'template_dir' => 'template/', //模板所在的文件夹
'compile_dir' => 'cache/', //模板编译后存放的目录
'html' => false, //是否需要编译为静态的HTML文件
'suffix_cache' => '.html', //编译文件的后缀
'cache_time' => 3600, //多长时间自动更新,单位,秒
'php' => true,
'cache_control' => 'control.dat',
'debug' => false
);
private $value = array();
private $compile_tool;
public $file; //模板名称
public $debug = array();
private $control_data = array();
static private $instance = null;
public function __construct($arrayConfig = array())
{
$this->debug['begin'] = microtime(true);
$this->arrayConfig = $arrayConfig + $this->arrayConfig;
$this->get_path();
if(!is_dir($this->arrayConfig['template_dir'])){
exit('template');
}
if(!is_dir($this->arrayConfig['compile_dir'])){
exit('compile');
}
include ('CompileClass.php');
}
public function get_path()
{
$this->arrayConfig['template_dir'] = strtr(realpath($this->arrayConfig['template_dir']),'\\','/')."/";
$this->arrayConfig['compile_dir'] = strtr(realpath($this->arrayConfig['compile_dir']),'\\','/')."/";
}
public static function get_instance()
{
if(is_null(self::$instance)){
self::$instance = new Template();
}
return self::$instance;
}
public function set_config($key,$value=null)
{
if(is_array($key)){
$this->arrayConfig = $key + $this->arrayConfig;
}else{
$this->arrayConfig[$key] = $value;
}
}
public function get_config($key=null)
{
if($key){
return $this->arrayConfig[$key];
}else{
return $this->arrayConfig;
}
}
public function assign($key,$value)
{
$this->value[$key] = $value;
}
public function assign_arr($array)
{
if(is_array($array)){
foreach ($array as $item=>$value) {
$this->value[$item] = $value;
}
}
}
public function path()
{
return $this->arrayConfig['template_dir'].$this->file.$this->arrayConfig['suffix'];
}
public function need_cache()
{
return $this->arrayConfig['html'];
}
public function re_cache($file)
{
$flag = false;
$cache_file = $this->arrayConfig['compile_dir'].md5($file).'.html';
if($this->arrayConfig['html'] == true){
$time_flag = (time()-@filemtime($cache_file)) < $this->arrayConfig['cache_time'] ? true : false;
if(is_file($cache_file) && filesize($cache_file) > 1 && $time_flag){
$flag = true;
}else{
$flag = false;
}
}
return $flag;
}
public function show($file)
{
$this->file = $file;
if(!is_file($this->path())){
exit('there is nothing to make');
}
$compile_file = $this->arrayConfig['compile_dir'].md5($file).".php";
$cache_file = $this->arrayConfig['compile_dir'].md5($file).".html";
if($this->re_cache($file) === false){
$this->debug['cached'] = 'false';
$this->compile_tool = new CompileClass($this->path(),$compile_file,$this->arrayConfig);
if($this->need_cache()){
ob_start();
}
extract($this->value,EXTR_OVERWRITE);
if (!is_file($compile_file) || filemtime($compile_file) < filemtime($this->path())) {
$this->compile_tool->vars = $this->value;
$this->compile_tool->compile();
include $compile_file;
}else{
include ($compile_file);
}
if($this->need_cache()) {
$message = ob_get_contents();
file_put_contents($cache_file,$message);
}
}else{
readfile($cache_file);
$this->debug['cached'] = true;
}
$this->debug['spend'] = microtime(true)-$this->debug['begin'];
$this->debug['count'] = count($this->value);
$this->debug_info();
}
public function debug_info()
{
if ($this->arrayConfig['debug'] == true) {
echo PHP_EOL.'———debug info———'.PHP_EOL;
echo "程序运行日期:".date("Y-m-d H:i:s").PHP_EOL;
echo "模板解析耗时:".$this->debug['spend']."秒".PHP_EOL;
echo "模板包含标签数目:".$this->debug['count'].PHP_EOL;
echo "是否使用静态缓存:".$this->debug['cached'].PHP_EOL;
echo "模板引擎实例参数:";
var_dump($this->get_config());
}
}
public function clean($path=null)
{
if($path=null) {
$path = $this->arrayConfig['compile_dir'];
$path = glob($path.'*'.$this->arrayConfig['suffix_cache']);
}else{
$path = $this->arrayConfig['compile_dir'].md5($path).".html";
}
foreach ($path as $item => $value) {
unlink($value);
}
}
}
接下来是编译类:
//CompileClass.php
class CompileClass{
private $template;
private $content;
private $compile;
private $left = '{';
private $right = '}';
private $value = array();
private $T_P = array();
private $T_R = array();
public function __construct($template,$compile_file,$config)
{
$this->template = $template;
$this->compile = $compile_file;
$this->content = file_get_contents($template);
if ($config['php'] == false) {
$this->T_P[] = '#<\?(=|php|)(.+?)\?>#is';
$this->T_R[] = '<?\\1\\2?>';
}
$this->T_P[] = '#\{\\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\}#';
$this->T_P[] = '#\{(loop|foreach)\\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)}#';
$this->T_P[] = '#\{\/(loop|foreach|if)}#i';
$this->T_P[] = '#\{([K|V])\}#';
$this->T_P[] = '#\{if(.*?)\}#i';
$this->T_P[] = '#\{(else if|elseif)(.*?)\}#i';
$this->T_P[] = '#\{else\}#i';
$this->T_P[] = '#\{(\#|\*)(.*?)(\#|\*)\}#';
$this->T_P[] = '#if\(\\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)#';
$this->T_R[] = "<?php echo \$this->value['\\1'];?>";
$this->T_R[] = "<?php foreach(\$this->value['\\2'] as \$K => \$this->value['V']){?>";
$this->T_R[] = "<?php } ?>";
$this->T_R[] = "<?php echo \$\\1;?>";
$this->T_R[] = "<?php if(\\1){ ?>";
$this->T_R[] = "<?php }else if(\\2){ ?>";
$this->T_R[] = "<?php }else{ ?>";
$this->T_R[] = " ";
$this->T_R[] = "if(\$this->value['\\1']";
}
public function compile()
{
$this->c_var2();
$this->c_static_file();
file_put_contents($this->compile,$this->content);
}
public function c_var2()
{
$this->content = preg_replace($this->T_P,$this->T_R,$this->content);
}
public function c_static_file()
{
$this->content = preg_replace('#\{\!(.*?)\!\}#','<script src=\\1'.'?t='.time().' ></script>',$this->content);
}
public function set($name,$value)
{
$this->$name = $value;
}
public function get($name)
{
return $this->$name;
}
}
然后是模板文件:
//asd.m
<html>
{!like.js!}
{$data},{$person}
<ul>
{loop$b}<li>{$V}</li>{/loop}
</ul>
{if$data == 'abc'}
abc
{elseif$data == 'def'}
def
{else}
{$data}
{/if}
{#############################################}
123456——
</html>
最后就是调用的代码:
//test.php
header('Content-type:text/html;charset=utf-8');
include 'Template.php';
$tpl = new Template(array('php'=>true,'debug'=>true));
$tpl->assign("data","hello word");
$tpl->assign("person","cafe cat");
$tpl->assign("pai",3.14);
$arr = array(1,2,3,4,5,"hat",7);
$tpl->assign('b',$arr);
$tpl->show('asd');
die;
目录结构如下:
模板文件放在这个位置:
最后我们会在下图位置看到编译后的文件:
从某种意义上来看的话,数据库也可以看做是优化过的、高效的文件存储的一种,我们对于变动少的,体积比较大的数据可以使用文件存储,反之,数据库比较合适,数据库比文件存储高级的地方就是,它解决了文件存储中很难解决的数据同步和锁的问题。所以说,是用什么存储,看大家的意思的,最重要的还是因地制宜,实现需求。
好啦,本次记录就到这里了。
如果感觉不错的话,请多多点赞支持哦。。。