Discuz!官方免费开源建站系统

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索

Discuz X2论坛css缓存的更新模式分析

[复制链接]
elevensky 发表于 2011-4-21 14:44:11 | 显示全部楼层 |阅读模式
一直很困惑于论坛的缓存更新中的extend_common.cssextend_module.css是如何被加载到模板缓存文件中的,看了看更新缓存的程序终于恍然大悟。呵呵,下面我们就来看看更新缓存的updatecache函数到底为我们做了些什么:
  1. function updatecache($cachename = '') {

  2.         $updatelist = empty($cachename) ? array() : (is_array($cachename) ? $cachename : array($cachename));

  3.         if(!$updatelist) {
  4.                 @include_once libfile('cache/setting', 'function');
  5.                 build_cache_setting();
  6.                 $cachedir = DISCUZ_ROOT.'./source/function/cache';
  7.                 $cachedirhandle = dir($cachedir);
  8.                 while($entry = $cachedirhandle->read()) {
  9.                         if(!in_array($entry, array('.', '..')) && preg_match("/^cache\_([\_\w]+)\.php$/", $entry, $entryr) && $entryr[1] != 'setting' && substr($entry, -4) == '.php' && is_file($cachedir.'/'.$entry)) {
  10.                                 @include_once libfile('cache/'.$entryr[1], 'function');
  11.                                 call_user_func('build_cache_'.$entryr[1]);
  12.                         }
  13.                 }
  14.         } else {
  15.                 foreach($updatelist as $entry) {
  16.                         @include_once libfile('cache/'.$entry, 'function');
  17.                         call_user_func('build_cache_'.$entry);
  18.                 }
  19.         }
  20. }
复制代码
这段代码中清晰的表达了缓存的更新流程。当我们执行updatecache函数的时候,如果你没有传给函数你要更新的模块就会更新所有的模板缓存。即./source/function/cache下所有的执行更新的函数文件都会被注意调用,并更新到缓存中。如果你只想单独更新一个模块的缓存,只需要把相应的参数传递给updatecachemodule)即可。
下面我们来看看,风格的css到底是以怎样的方式来加载的。下面我们打开风格的缓存生成文件,cache_styles.php下面我们来看看这个文件到底干了啥?
  1. $stylevars = $styledata = array();
  2.         $defaultstyleid = $_G['setting']['styleid'];
  3.         $query = DB::query("SELECT sv.* FROM ".DB::table('common_stylevar')." sv LEFT JOIN ".DB::table('common_style')." s ON s.styleid = sv.styleid AND (s.available=1 OR s.styleid='$defaultstyleid')");
  4.         while($var = DB::fetch($query)) {
  5.                 $stylevars[$var['styleid']][$var['variable']] = $var['substitute'];
  6.         }
复制代码
这一段代码根据你当前设定的模板,读取你当前模板的默认设置的值。并根据模板的id保存到$stylevars数组变量中。
  1. $query = DB::query("SELECT s.*, t.directory AS tpldir FROM ".DB::table('common_style')." s LEFT JOIN ".DB::table('common_template')." t ON s.templateid=t.templateid");
复制代码
取出每套模板的基本目录信息。然后下面开始对每套模板的变量数据进行逐一处理。
  1. $data = array_merge($data, $stylevars[$data['styleid']]);
  2.                 $datanew = array();
  3.                 $data['imgdir'] = $data['imgdir'] ? $data['imgdir'] : STATICURL.'image/common';
  4.                 $data['styleimgdir'] = $data['styleimgdir'] ? $data['styleimgdir'] : $data['imgdir'];
  5.                 foreach($data as $k => $v) {
  6.                         if(substr($k, -7, 7) == 'bgcolor') {
  7.                                 $newkey = substr($k, 0, -7).'bgcode';
  8.                                 $datanew[$newkey] = setcssbackground($data, $k);
  9.                         }
  10.                 }
  11. $data = array_merge($data, $datanew);
复制代码
对模板变量中背景属性标识bgcolor的变量拼合成css识别的backgroundcss样式。
  1. if(strstr($data['boardimg'], ',')) {
  2.                         $flash = explode(",", $data['boardimg']);
  3.                         $flash[0] = trim($flash[0]);
  4.                         $flash[0] = preg_match('/^http:\/\//i', $flash[0]) ? $flash[0] : $data['styleimgdir'].'/'.$flash[0];
  5.                         $data['boardlogo'] = "<embed src="".$flash[0]."" width="".trim($flash[1])."" height="".trim($flash[2])."" type="application/x-shockwave-flash" wmode="transparent"></embed>";
  6.                 } else {
  7.                         $data['boardimg'] = preg_match('/^http:\/\//i', $data['boardimg']) ? $data['boardimg'] : $data['styleimgdir'].'/'.$data['boardimg'];
  8.                         $data['boardlogo'] = "<img src="$data[boardimg]" alt="".$_G['setting']['bbname']."" border="0" />";
  9.                 }
复制代码
对前台logo的判定,分flash和图片的形式做相应的代码处理。
  1. if($data['extstyle']) {
  2.                         list($data['extstyle'], $data['defaultextstyle']) = explode('|', $data['extstyle']);
  3.                         $extstyle = explode("\t", $data['extstyle']);
  4.                         $data['extstyle'] = array();
  5.                         foreach($extstyle as $dir) {
  6.                                 if(file_exists($extstylefile = DISCUZ_ROOT.$data['tpldir'].'/style/'.$dir.'/style.css')) {
  7.                                         if($data['defaultextstyle'] == $dir) {
  8.                                                 $data['defaultextstyle'] = $data['tpldir'].'/style/'.$dir;
  9.                                         }
  10.                                         $content = file_get_contents($extstylefile);
  11.                                         if(preg_match('/\[name\](.+?)\[\/name\]/i', $content, $r1) && preg_match('/\[iconbgcolor](.+?)\[\/iconbgcolor]/i', $content, $r2)) {
  12.                                                 $data['extstyle'][] = array($data['tpldir'].'/style/'.$dir, $r1[1], $r2[1]);
  13.                                         }
  14.                                 }
  15.                         }
  16.                 }
复制代码
自定义风格信息的组装。
  1. foreach($styledata as $data) {
  2.                 save_syscache('style_'.$data['styleid'], $data);
  3.                 if($defaultstyleid == $data['styleid']) {
  4.                         save_syscache('style_default', $data);
  5.                 }
  6.                 writetocsscache($data);
  7.         }
复制代码
这里便开始对每套模板和默认模板分别做缓存。然后通过writetocsscache($data);此函数将所有模板的css做文件缓存。
下面来看看writetocsscache到底做了啥!

$dir =DISCUZ_ROOT.'./template/default/common/';
         $dh= opendir($dir);
         $data['staticurl']= STATICURL;

首先读取默认default套系模板中的css样式文件名,看看在当前模板中是否有同名的css文件,如果有就加载,如果没有则,加载默认的default文件夹下对应的css文件。然后加载当前模板是否有以extend_开头的扩展css样式,如果有加载到对应的css文件中。然后读取插件(plugin)模板中用的css
我打个比方:如果你当前有default,和teststyle两套风格。如果你teststyle中有common.css那么他就会加载你的这个common.css,但是很显然你不可能这么做,这是没有必要也是极其错误的方法。我们只会在原来的模板基础上添加我们扩展的css,即你的teststyle中只要加上extend_common.css,他就会追加到default/common/下的common.css这样我们就不会破坏原来整个论坛的风格样式了。
  1. $cssdata = preg_replace("/\{([A-Z0-9]+)\}/e", '\$data[strtolower(\'\1\')]', $cssdata);
  2.                         $cssdata = preg_replace("/<\?.+?\?>\s*/", '', $cssdata);
  3.                         $cssdata = !preg_match('/^http:\/\//i', $data['styleimgdir']) ? preg_replace("/url\((["'])?".preg_quote($data['styleimgdir'], '/')."/i", "url(\\1../../$data[styleimgdir]", $cssdata) : $cssdata;
  4.                         $cssdata = !preg_match('/^http:\/\//i', $data['imgdir']) ? preg_replace("/url\((["'])?".preg_quote($data['imgdir'], '/')."/i", "url(\\1../../$data[imgdir]", $cssdata) : $cssdata;
  5.                         $cssdata = !preg_match('/^http:\/\//i', $data['staticurl']) ? preg_replace("/url\((["'])?".preg_quote($data['staticurl'], '/')."/i", "url(\\1../../$data[staticurl]", $cssdata) : $cssdata;
  6.                         if($entry == 'module.css') {
  7.                                 $cssdata = preg_replace('/\/\*\*\s*(.+?)\s*\*\*\//', '[\\1]', $cssdata);
  8.                         }
  9.                         $cssdata = preg_replace(array('/\s*([,;:\{\}])\s*/', '/[\t\n\r]/', '/\/\*.+?\*\//'), array('\\1', '',''), $cssdata);
  10.                         if(@$fp = fopen(DISCUZ_ROOT.'./data/cache/style_'.$data['styleid'].'_'.$entry, 'w')) {
  11.                                 fwrite($fp, $cssdata);
  12.                                 fclose($fp);
复制代码
这段代码通过正则对,模板css,中的一些形如{IMGDIR}的一些变量做了解析,替换成标准的css.
另外最后要提到的一点是module.css这个文件支持模块化。这里只是对module统一的做解析。并没有将各个模块分装到不同的文件中去。
好了这里就基本上是css模板缓存的加载和解析机制。有兴趣的同学可以研究一下这些代码。





柏杉 发表于 2011-4-22 18:25:58 | 显示全部楼层
学习了,很不错!
回复

使用道具 举报

yinjie8888 发表于 2011-5-5 11:55:15 | 显示全部楼层
回复

使用道具 举报

星星光点 发表于 2011-5-11 16:33:14 | 显示全部楼层
不想要css缓存,怎么关闭,因为修改起来很麻烦,每次都要清除缓存才能看到效果。
回复

使用道具 举报

 楼主| elevensky 发表于 2011-5-11 17:37:03 | 显示全部楼层
星星光点 发表于 2011-5-11 16:33
不想要css缓存,怎么关闭,因为修改起来很麻烦,每次都要清除缓存才能看到效果。

出于对用户体验的观点来,不要这样做
回复

使用道具 举报

maomaodegege 发表于 2011-5-14 09:23:34 | 显示全部楼层
回复

使用道具 举报

918wz 发表于 2011-5-15 21:57:07 | 显示全部楼层
好好学习一下
回复

使用道具 举报

沐青年华 发表于 2011-5-21 20:54:51 | 显示全部楼层
不错 很有用的东西
回复

使用道具 举报

leixuok 发表于 2011-5-24 18:09:03 | 显示全部楼层
第一次在这里回帖,终于了解到我想要了解的内容了!谢谢了!
下载了好几个模板下来研究,都不是我想要的那种效果(有两个都是直接复制默认的common.css到自己模块下面然后改的,虽然确实能实现,但是感觉很不爽,严重同意楼主的意见)
回复

使用道具 举报

leixuok 发表于 2011-5-24 18:10:30 | 显示全部楼层
刚接触DZ两三天,请不要见笑
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|Discuz! 官方站 ( 皖ICP备16010102号 )star

GMT+8, 2024-11-16 16:29 , Processed in 0.046156 second(s), 5 queries , Gzip On, Redis On.

Powered by Discuz! X3.4

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表