写一些脚本的心得总结系列第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原生来得粗暴快速。

posted @   freephp  阅读(592)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示