檔案快取瞭解下
阿新 • • 發佈:2019-01-02
檔案快取就是指把快取資料儲存到檔案系統也就是硬碟中,大家都知道與記憶體相比,硬碟是屬於速度比較慢的儲存裝置,為什麼我們要使用這個呢???
原因很簡單,磁碟容量大,可以存放足夠多的資料,現在常規的硬碟已經進入到了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()
[email protected]($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;
目錄結構如下:
模板檔案放在這個位置:
最後我們會在下圖位置看到編譯後的檔案:
從某種意義上來看的話,資料庫也可以看做是優化過的、高效的檔案儲存的一種,我們對於變動少的,體積比較大的資料可以使用檔案儲存,反之,資料庫比較合適,資料庫比檔案儲存高階的地方就是,它解決了檔案儲存中很難解決的資料同步和鎖的問題。所以說,是用什麼儲存,看大家的意思的,最重要的還是因地制宜,實現需求。
好啦,本次記錄就到這裡了。
如果感覺不錯的話,請多多點贊支援哦。。。