zoukankan      html  css  js  c++  java
  • 写一些脚本的心得总结系列第5篇-----文件缓存和静态化

    6.改读缓存文件的。

    缓存除了memcache和redis这种key-value的存储外,还可以用文件缓存。一般这种方式都适合存一些变化不频繁的小量数据,比如地区表的数据。
    原理也很简单,就是读表数据,然后利用var_export到某个文件。

    代码如下:

    if (file_exists('cache/ad_position.cache.php')) {
        // 有缓存文件就读取缓存文件
        include 'cache/ad_posi.cache.php';
    } else {
        // get data from database
        $array = $this->mysql->select("select * from ad_posi");
    
        $data = array();
        //缓存地区信息。
        foreach ($array as $v) {
            $data[$v['id']] = $v;
        }
    
        $array = var_export($data, true);
        file_put_contents('cache/ad_posi.cache.php', "<?php return $data=$array;"); // 写入缓存文件
    }


    这种直接include进来数据对一些访问量很大的接口或应用效果非常好,但是也有一个问题,就是它是文件,除非被删除,否则没有过期时间,一旦对应的表数据发生变化,它不能及时自动的重新缓存。

    后来我在工作中就遇到过这种问题。思路有很多,比如

    1.重新写个脚本,每隔一秒去刷一次。
    2.开放一个专门的接口,允许手动刷新生成缓存文件。
    3.增加一个查询参数,就在原接口上调整。
    4.每当ad_posi表发生变化好后自动生成一次缓存文件。

    挨个分析一下可行性。第一种是比较费力的笨办法,相当于不断去轮询生成缓存文件,之前我们就说了,这个表作为广告位置表,一般来说一旦入库后改变的概率很小,让一个后台脚本每一秒去刷,有点杀鸡焉用宰牛刀的浪费。
    第二种允许单写一个接口手动生成缓存,绝对和现有代码较多重合的地方,虽然让接口保持了单一职责,但是也有吹毛求疵了。
    第三种想法ok,改写也简单,只用多传一个标识,判断是否刷新即可。
    第四种,是我个人比较喜欢的。原代码不用改一行,只用在可能让ad_posi改变的地方,重新生成一次缓存文件。
    但还是要看实际情况中,如果改变该表的地方较多,且在多个不同项目中的话,第四种就显得麻烦了。

    最终改为:

    $is_update = $this->input->get('is_update'); // 是否更新,true代表是
    if (file_exists('cache/ad_position.cache.php') && !$is_update) {
        // 有缓存文件且不主动更新就直接读取缓存文件
        include 'cache/ad_posi.cache.php';
    } else {
        // get data from database
        $array = $this->mysql->select("select * from ad_posi");
    
        $data = array();
        //缓存地区信息。
        foreach ($array as $v) {
            $data[$v['id']] = $v;
        }
    
        $array = var_export($data, true);
        file_put_contents('cache/ad_posi.cache.php', "<?php return $data=$array;"); // 写入缓存文件
    }

    其实全站静态化的原理也是类似,生成好后直接读取静态文件,以此提高页面加载速度。
    原理实现如下:

    ob_start();
    $name = 'freephp';
    echo <<<EOT
                <html>
                <head>
                <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
                <title>Untitled Document</title>
                </head>
                <body>
                <!--12321-->
                Hello,$name!
                </body>
                </html>
    EOT;
    
    $content = ob_get_contents();//取得php页面输出的全部内容
    $fp = fopen("user/show.html", "w");
    fwrite($fp, $content);
    fclose($fp);

    利用ob*系列函数来实现输出内容到文件,之后的访问就就是直接读取静态文件了,这对使用vps主机而不能使用redis之类缓存的童鞋,是很好的缓存方式。Smarty(对,好多人都不怎么用它了)也可以做到静态化,而且可以设置那些能缓存,那些部分不缓存。不过有一定学习成本,不如php原生来得粗暴快速。

  • 相关阅读:
    五一训练礼包 — B
    五一训练礼包—坐标问题
    单链表
    顺序表
    链表
    基础DP(3)
    基础DP(2)
    基础DP(1)
    分治法
    最小表示法
  • 原文地址:https://www.cnblogs.com/freephp/p/5094744.html
Copyright © 2011-2022 走看看