thinkCMF模板渲染的坑

  • 2023-11-07
  • df
  • 661

起因是,周末的时候,产品打电话来说公司网站无法打开,于是,我在家远程检查服务器,发现是磁盘空间满了,清理了一些压缩文件,然后,搜索了一下占空间的文件夹,发现是一个网站的temp目录满了,这个是thinkCMF的页面缓存文件目录,竟然达到了惊人的160G,而服务器总共才200G左右。

上班之后,研究了底层源码,发现是cmf本身的bug。

 

    const VERSION = '5.1.38 LTS';
 protected function fetch($template = '', $vars = [], $config = [])
    {
        $template = $this->parseTemplate($template);
        $more     = $this->getThemeFileMore($template);
        $this->assign('theme_vars', $more['vars']);
        $this->assign('theme_widgets', $more['widgets']);
        $content = $this->view->fetch($template, $vars, $config);

        $designingTheme = cookie('cmf_design_theme');

        if ($designingTheme) {
            $app        = $this->request->module();
            $controller = $this->request->controller();
            $action     = $this->request->action();

            $output = <<<hello
<script>
var _themeDesign=true;
var _themeTest="test";
var _app='{$app}';
var _controller='{$controller}';
var _action='{$action}';
var _themeFile='{$more['file']}';
if(parent && parent.simulatorRefresh){
  parent.simulatorRefresh();  
}
</script>
hello;

            $pos = strripos($content, '</body>');
            if (false !== $pos) {
                $content = substr($content, 0, $pos) . $output . substr($content, $pos);
            } else {
                $content = $content . $output;
            }
        }

        return parent::display($content, $vars, $config);;
    }

模板被渲染了两遍,第一次根据文件路径生成动态缓存,然后,对静态内容进行拼接,根据内容生成一个新的缓存文件,一旦动态内容发生改变,就会产生新的缓存文件,我们的页面里有个浏览量的数据,每次访问页面都会发生改变,这就每次访问页面都会产生新的缓存文件。

写这个项目的程序员已经离职了,这个项目已经上线运行很长时间了,也就是说这个bug一直运行了很久,导致垃圾缓存不断产生。

 

    const VERSION = '5.1.39 LTS';
 protected function fetch($template = '', $vars = [], $config = [])
    {
        $template = $this->parseTemplate($template);
        $more     = $this->getThemeFileMore($template);
        $this->assign('theme_vars', $more['vars']);
        $this->assign('theme_widgets', $more['widgets']);
        $content = $this->view->fetch($template, $vars, $config);

        $designingTheme = cookie('cmf_design_theme');

        if ($designingTheme) {
            $app        = $this->request->module();
            $controller = $this->request->controller();
            $action     = $this->request->action();

            $output = <<<hello
<script>
var _themeDesign=true;
var _themeTest="test";
var _app='{$app}';
var _controller='{$controller}';
var _action='{$action}';
var _themeFile='{$more['file']}';
if(parent && parent.simulatorRefresh){
  parent.simulatorRefresh();  
}
</script>
hello;

            $pos = strripos($content, '</body>');
            if (false !== $pos) {
                $content = substr($content, 0, $pos) . $output . substr($content, $pos);
            } else {
                $content = $content . $output;
            }
        }

        return $content;
    }

这是框架的下一个版本,明显开发者发现了bug,然后进行了修复。

之前服务器出现过缓存占满的情况,但是之前程序员只是清理了缓存,并没有排查问题,导致这个问题一直持续到现在,其实只需要升级一下框架就好了。

然而,之前那个程序员估计连composer都不会用,根本就不知道这玩意儿还能直接升级,他是直接在vendor目录里进行开发,根本没考虑清楚框架bug和框架升级的问题,然后,他之后做的另一个项目是用的`5.1.39`的版本,所以,另一个项目没有类似的问题,所以,那个项目的缓存是正常的,而这个项目一直在疯狂占用磁盘空间。