dedecms代码研究五
上一次留几个疑问: 1)DedeTagParse类LoadTemplet方法。 2)MakeOneTag到底在搞什么。
从DedeTagParse开始
前面,我们一直在dedecms的外围,被各种全局变量和各种调用所迷惑,我们抓住了一个关键的线索DedeTagParse类,研究明白它,就可以弄清楚很多东西了。
看看这个NB的DedeTagParse类吧。
嗯,先看构造函数,没什么特别的,就是设置了一堆初始化参数。
接下来就找LoadTemplet方法吧。
找到后,我们发现LoadTemplet方法其实是指向LoadTemplate方法的,无语啊,难道作者英文就差到此等地步?
看看那个LoadTemplate方法吧。
function LoadTemplate($filename)
{
$this->SetDefault();
if(!file_exists($filename))
{
$this->SourceString = " $filename Not Found! ";
$this->ParseTemplet();
}
else
{
$fp = @fopen($filename, "r");
while($line = fgets($fp,1024))
{
$this->SourceString .= $line;
}
fclose($fp);
if($this->LoadCache($filename))
{
return '';
}
else
{
$this->ParseTemplet();
}
}
}
里面先用SetDefault方法设置了几个初始变量:
$this->SourceString = '';
$this->CTags = '';
$this->Count=-1;
然后判断模板文件是否存在。然后针对不同情况对$this->SourceString赋值,并调用$this->ParseTemplet();方法。
这块的代码看出来,作者开发功力有待改进啊,都5.6了,代码重构还如此糟糕,唉~为什么不能把$this->ParseTemplet();这句放在if外面呢?
文件不存在时候,很简单,就是把“文件不存在”这句话放到$this->SourceString中,然后调用$this->ParseTemplet();。
文件存在的时候,也很简单,fgets读取文件内容(麻烦,为啥不用file_get_contents呢),然后,又是一个if,通过$this->LoadCache($filename)返回值判断是否有缓存,如果返回true说明读取到缓存的模板了,就返回空字符串(怎么可以这样呢?返回值也太不负责了吧),如果返回false就调用$this->ParseTemplet();重新解析模板。
LoadTemplate大致就是这些,无非是读取模板文件内容,然后看是否有缓存,有就不解析模板,没有就解析模板,仅此而已。
我们接下来看看$this->LoadCache方法吧,找到方法定义的部分,呀喝,代码还不少。
先是通过$this->IsCache判断是否允许缓存(这个属性是在DedeTagParse类实例化的时候设定的,跟dedecms的系统配置中是否加模板缓存的参数$cfg_tplcache有关,这个在DedeTagParse类的构造函数中有所体现,由于安装dedecms后,默认系统配置为true,所以这里默认就为true啦),如果为false的话,$this->LoadCache就返回false而不继续向下走了,在LoadTemplate方法中就会根据这个返回值来决定解析模板。
过了$this->IsCache这关,程序继续。下面就是找当前模板文件对应的缓存了。
dedecms的文件缓存有点特别,我们找到模板缓存目录(data/tplcache),观察一下就会发现,很多名字有点相同的文件,仔细看看还能找出点规律来。我们从代码来印证一下吧。
上面说到LoadCache方法中,我们过了$this->IsCache这关,后面就是找模板文件了,我们看看后面的代码:
$cdir = dirname($filename); $cachedir = DEDEROOT.$cfg_tplcache_dir; $ckfile = str_replace($cdir,'',$filename).substr(md5($filename),0,16).'.inc'; $ckfullfile = $cachedir.'/'.$ckfile; $ckfullfile_t = $cachedir.'/'.$ckfile.'.txt';
前3句是拼缓存文件名字的,方法是取不带目录的模板文件名然后md5进行hash,然后把hash出来的字符串取前16个字符,后面加上“inc”后缀就成了。
第4句是取得完整的缓存文件名。
第5距好像是另一个文件名字,就是在缓存文件名字后面再加个后缀“.txt”
上面就得到了两个文件名字,但是我们不知道第二个文件名字干什么用的,再继续往下看咯啊的代码吧。
$this->CacheFile = $ckfullfile;
$this->TempMkTime = filemtime($filename);
if(!file_exists($ckfullfile)||!file_exists($ckfullfile_t))
{
return false;
}
第1句就指定了当前模板的缓存文件
第2句读取了文件的最后修改时间,设置了一个什么时间的属性,现在还不大明白。
接下来的if语句就是如果找不到模板的两个缓存文件(就是上面组合出来的两个文件),就返回false让LoadTemplate方法解析模板去。
我们假设模板的缓存文件都有,继续看代码。下面代码段写了注释,就是检测模板最后更新时间,代码很简单,就是打开我们前面说的那个$ckfullfile_t变量指定的txt文件,读内容,然后把内容和缓存修改时间比较,原来.txt文件是用来保存缓存文件的保存时间的。如果时间不一致则就返回false让LoadTemplate方法解析模板去。
我们假定缓存有效,那么就可以继续了。
缓存有效就会把缓存文件包含进来。
这块就要根据缓存文件来具体分析了,所以,我们这里假定载入的是index.htm模板吧,在tplcache里面找到index.htm开头,后缀为inc的文件,打开。
我们这里节选一部分:
$z[0]=Array("global","",236,264);
$z[0][4]['name']="cfg_soft_lang";
$z[1]=Array("global","",277,303);
$z[1][4]['name']="cfg_webname";
$z[2]=Array("global","",347,377);
$z[2][4]['name']="cfg_description";
$z[3]=Array("global","",414,441);
$z[3][4]['name']="cfg_keywords";
……
再回到我们的LoadCache方法里面。
前面说到include了模板缓存文件,然后,下面的if语句判断的是缓存文件里面的信息数组“$z”是否正常,如果正常就进行来个foreach循环,这个foreach很重要。我们来看看代码。
//把缓冲数组内容读入类
if( isset($z) && is_array($z) )
{
foreach($z as $k=>$v)
{
$this->Count++;
$ctag = new DedeTAg();
$ctag->CAttribute = new DedeAttribute();
$ctag->IsReplace = FALSE;
$ctag->TagName = $v[0];
$ctag->InnerText = $v[1];
$ctag->StartPos = $v[2];
$ctag->EndPos = $v[3];
$ctag->TagValue = '';
$ctag->TagID = $k;
if(isset($v[4]) && is_array($v[4]))
{
$i = 0;
foreach($v[4] as $k=>$v)
{
$ctag->CAttribute->Count++;
$ctag->CAttribute->Items[$k]=$v;
}
}
$this->CTags[$this->Count] = $ctag;
}
}
这是个遍历缓存信息数组,然后每个$z数组的元素,都生成一个DedeTAg对象,并把$z数组元素的一些信息赋给DedeTAg对象,我们经过看这段源代码,发现,$z数组元素中,0是标签名称(TagName),1是内部文本(InnerText),2是开始位置(StartPos),3是结束位置(EndPos)。新的DedeTag对象的tagID就是数组下标。
这里面还有个循环,是循环$z数组每个元素的第四个子元素。然后,然后把相关值赋到当前DedeTAg对象的DedeAttribute对象中。
看到这里,我们似乎明白点东西了。
1)tplcache里面存的并不是解析好的模板,而是一堆信息数组。(其实后面会分析到的模板解析方法DedeTagParse类中的ParseTemplet也只是把模板标签信息记录下来)
2)信息数组里保存的都是一个模板页里面包含的所有标签的信息。
3)上面的循环其实是把缓存里面的标签信息读取并写入DedeTAg对象,然后保存到当前DedeParse类的CTags数组中,到目前DedeParse的实例得到了模板内容(在$this->SourceString中),模板上所有标签信息(在 $this->CTags中)。
好了,经过上面的一番操作,LoadCache方法就这些了,缓存读取完成,这样就可以安心回到LoadTemplate方法里面去继续分析了。
dedecms代码研究五的更多相关文章
- dedecms代码研究二
dedecms代码研究(2)从index开始现在继续,今天讲的主要是dedecms的入口代码.先打开index.PHP看看里面是什么吧.打开根目录下的index.php嗯映入眼帘的是一个if语句.检查 ...
- dedecms代码研究七
简单回顾一下,前面我们首页动态文件index.PHP调用arc.partview.class.php来初始化首页模板 arc.partview.class.php通过SetTemplet调用DedeT ...
- dedecms代码研究四
partview php文件之前,我们像掉进沼泽一样,看到无尽的变量,数组元素,莫名其面的东西摆在我们面前.今天,我们继续艰难前行,想办法走出partview类的泥潭.上一篇,我们胡乱分析了partv ...
- dedecms代码研究一
dedecms相信大家一定都知道这个cms系统,功能比较强大,有比较完善的内容发布,还有内容静态化系统,还有就是它有自己独特的标签系统和模板系统.而模板系统也是其他cms系统比较难模仿的的东西,这个东 ...
- dedecms代码研究六
今天讲的是dedecms最关键的东西,模板分析啦.也就是dedetag.class.php 里面的ParseTemplet方法 模板解析方法 先看看一个dedecms标签,大家心里有个数: {dede ...
- dedecms代码研究三
上次,我们从dedecms的index.PHP文件中了解到了很多信息,也提出了一些问题: 1)加载了/include/common.inc.php,里面做了哪些工作? 2)/include/arc.p ...
- (转)dedecms代码详解 很全面
dedecms代码研究(1)开篇dedecms 相信大家一定都知道这个cms 系统,功能比较强大,有比较完善的内容发布,还有内容静态化系统,还有就是它有自己独特的标签系统和模板系统.而模板系统也是其他 ...
- dedecms代码详解 很全面
dedecms代码研究(1)开篇dedecms 相信大家一定都知道这个cms 系统,功能比较强大,有比较完善的内容发布,还有内容静态化系统,还有就是它有自己独特的标签系统和模板系统.而模板系统也是其他 ...
- [转载]iOS6新特征:UICollectionView官方使用示例代码研究
原文地址:iOS6新特征:UICollectionView官方使用示例代码研究作者:浪友dans 注:这里是iOS6新特征汇总贴链接 iOS6新特征:参考资料和示例汇总 这个链接可以学习到UIColl ...
随机推荐
- 修改input的type属性
在ff和chrome中是可以直接修改input的type属性的,但是在ie下面是不允许的. 用jquery 的attr方法去修改,在jquery1.8.3版本会直接抛出异常,但在1.9及以上版本就不再 ...
- Objective-C学习笔记-第一天(1)
.h头文件,用于声明一些公开的属性.方法.头文件一般不会放太多的东西,没必要暴露太多接口,私有和封装. .m主文件,用于实现.h文件中的方法,以及一些其它的方法. -(返回值)方法名参数1名称:(参数 ...
- myawr : mysql性能监控
myawr以mysql instance 为单位,每隔一段时间进行采样,然后把数据保存到数据库,以便分析.目前myawr脚本收集的信息包括5个部分: 1 系统方面的:负载.cpu.io.网络.swap ...
- Windows Server 2012 R2在桌面上顯示我的電腦等圖示
Windows Server 2012 R2在桌面上顯示我的電腦等圖示 從Windows2012開始,微軟取消了服務器桌面個性化選項,如何重新調出配置界面,可以使用微軟命令調出.方法如下: 同時按 ...
- B/S和C/S测试的区别
B/S(Brower/Server)以访问方式为主,包含客户端浏览器.web应用服务器.数据库服务器的软件系统.一般的B/S结构,都是多层架构的,有界面层.业务逻辑层.数据层.由于这种结构不需 ...
- HTTP协议(缓存机制Cache)
HTTP的缓存 至于响应消息的实体,与请求消息的实体内容相似,这里只借绍下User-Agent头 User-Agent头域的内容包含发出请求的用户信息. Cache-Control头域(请求和应答通用 ...
- tf.slice可以用于矩阵也就是图片的切割
第一个向量表示切割的起点,第二个向量表示矩形框的大小,-1表示取该元素的最大值
- hdu2191 悼念512汶川大地震 ——多重背包
link:http://acm.hdu.edu.cn/showproblem.php?pid=2191 最简单的那种 #include <iostream> #include <cs ...
- struts2 ajax的一种实现方式
/** * ajax请求,通过省份id获取学习中心 */ public void getSitesByPid() { HttpServletResponse response = ServletAct ...
- mysql保存数据提示1366 Incorrect string value: ‘\xF0\x9F\x98\x8A\xF0\x9F…’ 解决
在保存数据时我们如果页面编辑与数据库字段编码不一样或字符集超出你了mysql数据库中的字符类型就有可能出一\\xF0\\x9F\\x98\\x8A\\xF0\\x9F提示了,下面我来简单的解决方法. ...