文件缓存了解下

文件缓存就是指把缓存数据存储到文件系统也就是硬盘中,大家都知道与内存相比,硬盘是属于速度比较慢的存储设备,为什么我们要使用这个呢???

原因很简单,磁盘容量大,可以存放足够多的数据,现在常规的硬盘已经进入到了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[] = '&lt;?\\1\\2?&gt';
        }
        $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;

目录结构如下:

模板文件放在这个位置:

最后我们会在下图位置看到编译后的文件:

从某种意义上来看的话,数据库也可以看做是优化过的、高效的文件存储的一种,我们对于变动少的,体积比较大的数据可以使用文件存储,反之,数据库比较合适,数据库比文件存储高级的地方就是,它解决了文件存储中很难解决的数据同步和锁的问题。所以说,是用什么存储,看大家的意思的,最重要的还是因地制宜,实现需求。

好啦,本次记录就到这里了。

如果感觉不错的话,请多多点赞支持哦。。。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

luyaran

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值