【SQL开源代码栏目提醒】:网学会员鉴于大家对SQL开源代码十分关注,论文会员在此为大家搜集整理了“dedecms程序代码系统讲解 - 网站开发与设计”一文,供大家参考学习
sourcejoy 之 dedecms
代码研究(1)开篇 dedecms 相信大家一定都知道这个 cms 系统,功能比较强大,有比较完善的内容发布,还有内容静态化系统,还有就是它有自己独特的标签系统和模板系统。
而模板系统也是其他 cms 系统比较难模仿的的东西,这个东西还是需要一点开发功力和技巧的。
本系列文章就研究一下 dedecms 的这套系统,挖掘一下看看里面有什么好东西。
官方网站:http://www.dedecms.com 本文使用的是 5.6 版的 dedecms 建议大家先了解一下 dedecms 的功能。
自己先动手用一下,对系统功能有个大概了解。
本文先带领大家了解一下 dedecms 的
代码和功能架构。
其实,dedecms 在架构上没什么应用架构模式可言,就是最简单的 PHP 应用而已。
访问不同的 PHP 文件,管理不同的系统功能。
看目录大家都能猜出来各个目录干什么用的。
include 目录放系统的一些公用函数和类,plus 目录放插件,templates 目录放模板,dede 目录是管理后台目录。
我们打开 include 目录,看看里面都有什么好东西。
calendar 一个选时间的 js captcha 一个验证码,还是
开源组件 code 没啥意思,翻页的文字 data 里面是一些系统用到的资源,比如声音,分词库,字体,图片等 dialog 里面估计是一些 AJAX 弹出窗口的内容部分。
以后碰到了再说 inc 里面一些单独的功能类函数,以后研究一下为什么要单独放 payment 支付接口 taglib 好东西,是 dedecms 的标签存放的地方,打开看看,里面一堆文件,貌似就是 dedecms 的模板标签啦 tpllib 模板库?暂时搞不明白,希望随着研究深入,能弄明白 其他 include 目录下的文件估计都是一些最基本的功能文件啦,比如常用函数,模板系统之类的东西了。
用到再说吧 打开 dede 目录(就是 dedecms 的管理目录)看看,哟嗬,里面的东西还挺多,看名字就知道了,都是各种功能管理文件,一个功能一个文件。
最原始的网站开发模式做出来的。
我们姑且称之为高效吧。
毕竟 PHPwind和 discuz 之类也是用类似的方法开发的。
整个程序大体就这些东西啦。
功能就不讲了,建议不熟悉 dedecms 的朋友自己看一下 dedecms 的后台管理功能,这样能有助于我们更好理解和分析它。
另外提一点,我们的这次
代码分析,主要分析的是其页面生成、显示、模板处理、标签处理部分,这套系统也是 dedecms 比较引以为傲的东西,之后呢,还会分析一些笔者觉得比较酷的功能
代码。
最后,希望这次
代码分析旅程能让大家有所收获。
sourcejoy 之 dedecms
代码研究(2)从 index 开始 现在继续,今天讲的主要是 dedecms 的入口
代码。
先打开 index.php 看看里面是什么吧。
打开根目录下的 index.php 嗯,映入眼帘的是一个 if 语句。
检查/data/common.inc.php 是否存在。
如果不存在就跳转到安装界面。
我们来到/data/看看这个目录和 common.inc.php。
打开/data/,里面很多目录和文件,有上传的临时目录,模板缓存,压缩的临时目录,各种数据库里保存的系统配置信息的缓存文件以及其他的一些东西,就一个字乱~ 好吧, 哦, 我们打开 common.inc.php。
原来就是保存了数据库连接的相关变量而已。
说白了,就是 dedecms的数据库连接配置文件,估计是安装完系统生成的。
所以/index.php 会检查它是否存在。
我们回到/index.php 中继续往下看,第二个 if 语句,判断 GET 请求“upcache”是否存在,存在就更新首页缓存,不存在就直接 301 跳转到 index.html,也就是 dedecms 的静态首页(记住,dedecms 的前台页面都是系统生成的静态页面)。
想想接下来我们要研究什么?对,就是 GET 请求“upcache”存在的时候,更新首页缓存这小段
代码啦。
代码如下:require_once dirname__FILE__ . quot/include/common.inc.phpquotrequire_once DEDEINC.quot/arc.partview.class.phpquotGLOBALS_arclistEnv indexrow dsql-gtGetOnequotSelect From __homepagesetquotrowtemplet MfTempletrowtempletpv new PartViewpv-gtSetTempletcfg_basedir . cfg_templets_dir . quot/quot . rowtempletpv-gtSaveToHtmldirname__FILE__./index.htmlincludedirname__FILE__./index.htmlexit 先是加载/include/common.inc.php,估计是一些常用函数和加载其他系统函数和类的文件。
接下来又加载了 DEDEINC.quot/arc.partview.class.phpquot,注意 DEDEINC 这个常量,我们知道经过前期对dedecms 目录结构观察,arc.partview.class.php 是在/include 目录下的,而加载/include/common.inc.php 却没有用DEDEINC 这个常量,这说明,common.inc.php 里面定义了 DEDEINC 这个常量,所以后面得以使用,也印证了 common.inc.php 大体作用就是系统运行基本部分,都在这里面啦。
我们不急着进 common.inc.php,继续把index.php 的更新缓存
代码看完。
第三句,设置了一个全局变量:GLOBALS_arclistEnv index 第 四 行 , 获 取 一 个 表 __homepageset 的 所 有 记 录 , 当 然 如 果 你 看 下 数 据 库 , 里 面 没 有“__homepageset”这个表,我们判断,是数据库操作相关函数把表名用表名前缀替换了一下前半部分,这个都不重要了,重要的是,通过这句,获取了首页的相关配置信息,我们打开数据库里面的 dede_homepageset表,晕,就一条记录,俩字段,基本猜到了,一个是首页模板名称,一个是生成的静态文件的位置。
回来继续分析前面的
代码 rowtemplet MfTempletrowtemplet 通过 MfTemplet 函数好像把rowtemplet进行了某些转换。
我们记下 MfTemplet 函数,以待后面挖掘。
接下来,就是 new 了一个 PartView 类,看这个名字,我们就知道了前面加载 arc.partview.class.php 的作用啦。
至于这个 PartView 类有什么作用,我们继续看
代码。
看了下面两行,我想大家应该都明白啦pv-gtSetTempletcfg_basedir . cfg_templets_dir . quot/quot . rowtempletpv-gtSaveToHtmldirname__FILE__./index.html 创建个视图对象(PartView 类的实例,我们姑且叫视图对象),设置模板,通过 SaveToHtml 方法,把最后生成的页面写到指定位置。
首页生成完毕,接下来就是把生成的静态文件通过 include 的形式显示出来,然后 exit 中断页面解析。
至此,/index.php 就分析完啦。
它先是通过/data/common.inc.php,判断是否安装了 dedecms 或者说判断是否定义了数据库配置信息,好为后面操作打下基础。
然后判断是否有 GET 请求quotupcachequot,如果有就加载/include/common.inc.php 初始化系统,然后调用partview 类的相关方法来生成静态首页文件,最后显示出来。
这么来看 dedecms 也没有太多的秘密嘛~ 不过呢,我们这篇文章也遗留下了几个问题: 1)加载了/include/common.inc.php,里面做了哪些工作? 2)/include/arc.partview.class.php 到底是干什么的,/include/下还有很多 arc 开头的文件都是干什么的? 3)MfTemplet 这个函数到底对模板文件路径这个字符串做了什么操作? 4)partview 类的相关方法都有什么秘密? 带着这几个疑问,我们将结束本文,后面的文章将将这些谜题一一揭开。
sourcejoy 之 dedecms
代码研究(3)partview 的迷惑上次,我们从 dedecms 的 index.php 文件中了解到了很多信息,也提出了一些问题,本文开始就带着前面的问题,继续我们的 dedecms 之旅吧。
先回顾一下之前我们在 index.php 文件研究中总结的东西。
首先加载 common.inc.php,接下来组织模板,生成静态页面并跳到静态页面。
接下来,我们就先来看看 common.inc.php 里面都有什么吧。
打开/include/common.inc.php 里面的注释已经说地比较清楚了。
我们大概说说结构。
先是定义一堆常量。
然后是做一些安全措施,对 PHP 的系统环境进行一些设置,
代码里面的注释已经写地很清楚了。
接下来是把 dedecms 的系统配置参数文件包含进来:require_onceDEDEDATA.quot/config.cache.inc.phpquot看文件名字,我们猜测这个配置文件可能是数据库里面的配置信息的缓存。
接下来加载了数据库配置信息文件:require_onceDEDEDATA./common.inc.php 这个文件,不是根据数据库中信息生成的缓存,而是 dedecms 安装的时候生成的。
前一篇文章我们说过index.php 文件开始,检测 dedecms 是否安装,就是看这个文件是否存在的。
再接下来,整理了很多目录,比如:站点根目录、模板目录,插件目录、数据目录等,还整理了很多变量。
最后加载了数据库操作类 dedesql.class.php 和常用函数文件 common.func.php 嗯,common.inc.php 的谜底揭开,里面没什么好玩的东西啦,都是最基本的东西。
接下来我们就得看看 arc.partview.class.php 吧,这里面可是 dedecms 关键呢 加载了 channelunit.class.php,typelink.class.php,ftp.class.php 下面就是 partview 类的定义啦 因为 index.php 中使用 partview 类的 SetTemplet 方法和 SaveToHtml 方法,所以,我们为了能更简单地深入,就从这两个方法着手。
我们先看看 partview 的构造函数。
创建了一个 DedeTagParse 类的实例,看名字是标签解析类哦。
然后设置了几个参数。
接下来,new 了一个 TypeLink 类,设置了一堆参数。
搞的很云里雾里的。
看看 SetTemplet 吧。
啊,这个还算简单。
先,使用 DedeTagParse 类的 LoadTemplet 方法载入模板。
再,设置一些 Fields 数组的元素最后,调用 ParseTemplet 方法。
ParseTemplet 方法里面弄了一堆GLOBALS 数组的元素,然后调用了 MakeOneTag 函数。
费解啊再看看 SaveToHtml 方法吧,前面就是建目录,最后用 DedeTagParse 的 SaveTo 方法保存到文件。
呃~不给力啊。
只能回头想想,都看到了什么~嗯,为了能生成首页,搞了个很搞不懂的 partview 类,然后里面调用了貌似万能的 DedeTagParse 方法,解析模板,生成静态文件。
仅此而已。
里面还夹杂了其他函数和类,但不管怎么样这个 DedeTagParse 是重点,下次得重点分析了。
今天就到这吧,鸟儿的~太乱了,一点章法都没有~ sourcejoy 之 dedecms
代码研究(4)继续徘徊 partview之前,我们像掉进沼泽一样,看到无尽的变量,数组元素,莫名其面的东西摆在我们面前。
今天,我们继续艰难前行,想办法走出 partview 类的泥潭。
上一篇,我们胡乱分析了 partview 类,完全搞不懂干什么的,里面弄了一堆变量,最清晰的我们只是知道几个生成首页的关键地方调用了 DedeTagParse 类的 LoadTemplet 方法和 SaveTo 方法。
而在 partview 类定义的文件头部,包含了几个文件,我们就避开 partview,先来看看这几个包含的文件吧。
require_onceDEDEINC./channelunit.class.phprequire_onceDEDEINC./typelink.class.phprequire_onceDEDEINC./ftp.class.phpftp.class.php,不用说,就是 ftp 相关操作类吧,我们之前看 partview
代码的时候,了解到,在生成静态文件的时候,使用了 ftp相关方法,貌似就是可以远程写文件滴。
至于怎么操作 FTP 的,其实就是封装了 php 函数库中 ftp 开头的相关函数而已,
代码很简单,不说了。
typelink.class.php,我们也在 partview
代码里面见过的,打开看看吧。
大概看了一下
代码,里面是 type 的链接相关的东西,每个方法都声称一个指定 type 的链接 html 字符串。
其实,我有点隐约感觉到在 dedecms 中,type 就是指栏目,不知道是不是这样。
再来看看 channelunit.class.php 吧。
里面是 ChannelUnit 类的定义,而且我们发现,这个 ChannelUnit 类没有被使用过。
所以先不去看他。
我们注意到,这里面还加载了两个文件:require_onceDEDEINC.quot/dedetag.class.phpquotrequire_onceDEDEINC.quot/channelunit.func.phpquotdedetag.class.php,打开看看,嗯,很复杂,但我们发现用于解析模板和生成文件的 DedeTagParse 类在里面,呵呵,先记住,以后慢慢研究。
channelunit.func.php 里面都什么函数呢?打开一看,嗯,一堆变量,几个获取这种信息的函数,在我们浏览过程中,发现了两个函数:MfTemplet 和 MakeOneTag我们知道,在 index.php 中就用了 MfTemplet 函数,回头打开 index.php 看看怎么调用的:rowtemplet MfTempletrowtemplet我们之前了解过,rowtemplet保存的是 default/index.htm 这个值,就是模板文件路径。
接下来我们看看 MfTemplet 函数都做了什么吧。
//模板目录规则function MfTemplettmpdir tmpdir str_replacequotstylequotGLOBALScfg_df_styletmpdir tmpdir ereg_replacequot/1quotquot/quottmpdir return tmpdir注释里面写的是“模板目录规则”,再看看
代码,哦,仿佛明白了一点儿了,就是替换模板路径里面的style为全局变量GLOBALScfg_df_style中的值。
应该跟使用不同模板套系有关吧。
意义不是很大就不再继续研究了。
我们看另一个函数 MakeOneTag,这个在 partview 类的 ParseTemplet 方法中,此方法看名字就是解析模板,而方法的大部分
代码都是在处理变量,看不大懂干什么的,最后一句调用了 MakeOneTag 函数。
貌似主要解析模板就是靠这个函数了。
使用如下:MakeOneTagthis-gtdtpthis第一个参数是 DedeTagParse 类的实力,第二个参数就是 partview 类实例的句柄啦。
我们看看 channelunit.func.php 中这个函数是干什么的吧。
嗯,只能大概看,因为好多东西,我们都不清楚啊,郁闷了。
这里面遍历了/include/taglib/下所有有 lib 后缀的文件,并把文件路径加入数组,然后对 DedeTagParse 类的 CTag 进行了遍历,由于我们没有研究 DedeTagParse 类,所以这块暂时不懂呢,不过也算小有进展了。
看来还得回到 partview 里面去重新看看了。
构造函数没什么特别的,就是创建了 DedeTagParse 类实例,进行了一些设置而已。
我们知道 index.php 创建 partview 实例后执行了 SetTemplet 方法,我们再看看 SetTemplet 方法吧。
这里面调用了 DedeTagParse 类实例的 LoadTemplet 方法,看来我们就得从这里入手,去抽丝剥茧啦。
分析不下去了~留几个疑问下次再说。
1)DedeTagParse 类 LoadTemplet 方法说开去。
2)MakeOneTag 到底在搞什么。
看来只有彻底先把 DedeTagParse 类 LoadTemplet 方法搞懂才能进一步啊,目前还是一头雾水。
sourcejoy 之 dedecms
代码研究(5)从 DedeTagParse 开始前面,我们一直在 dedecms 的外围,被各种全局变量和各种调用所迷惑,我们抓住了一个关键的线索 DedeTagParse 类,研究明白它,就可以弄清楚很多东西了。
看看这个 NB 的 DedeTagParse 类吧。
嗯,先看构造函数,没什么特别的,就是设置了一堆初始化参数。
接下来就找 LoadTemplet 方法吧。
找到后,我们发现 LoadTemplet 方法其实是指向 LoadTemplate 方法的,无语啊,难道作者英文就差到此等地步?看看那个 LoadTemplate 方法吧。
里面先用 SetDefault 方法设置了几个初始变量:this-gtSourceString this-gtCTags this-gtCount-1然后判断模板文件是否存在。
然后针对不同情况对this-gtSourceString 赋值,并调用this-gtParseTemplet方法。
这块的
代码看出来,作者开发功力有待改进啊,都 5.6 了,
代码重构还如此糟糕,唉~为什么不能把this-gtParseTemplet这句放在 if 外面呢?文件不存在时候,很简单,就是把“文件不存在”这句话放到this-gtSourceString 中,然后调用this-gtParseTemplet。
文件存在的时候,也很简单,fgets 读取文件内容(麻烦,为啥不用 file_get_contents 呢),然后,又是一个 if,通过this-gtLoadCachefilename返回值判断是否有缓存,如果返回 true 说明读取到缓存的模板了,就返回空字符串(怎么可以这样呢?返回值也太不负责了吧),如果返回 false 就调用this-gtParseTemplet重新解析模板。
LoadTemplate 大致就是这些,无非是读取模板文件内容,然后看是否有缓存,有就不解析模板,没有就解析模板,仅此而已。
我们接下来看看this-gtLoadCache 方法吧,找到方法定义的部分,呀喝,
代码还不少。
先是通过this-gtIsCache 判断是否允许缓存(这个属性是在 DedeTagParse 类实例化的时候设定的,跟 dedecms 的系统配置中是否加模板缓存的参数cfg_tplcache 有关,这个在 DedeTagParse 类的构造函数中有所体现,由于安装 dedecms 后,默认系统配置为 true, , this-gtLoadCache 就返回 false 而不继续向下走了, LoadTemplate 所以这里默认就为 true 啦)如果为 false 的话, 在方法中就会根据这个返回值来决定解析模板。
过了this-gtIsCache 这关,程序继续。
下面就是找当前模板文件对应的缓存了。
dedecms 的文件缓存有点特别,我们找到模板缓存目录(data/tplcache),观察一下就会发现,很多名字有点相同的文件,仔细看看还能找出点规律来。
我们从
代码来印证一下吧。
上面说到 LoadCache 方法中,我们过了this-gtIsCache 这关,后面就是找模板文件了,我们看看后面的
代码:cdir dirnamefilenamecachedir DEDEROOT.cfg_tplcache_dirckfile str_replacecdirfilename.substrmd5filename016..incckfullfile cachedir./.ckfileckfullfile_t cachedir./.ckfile..txt前 3 句是拼缓存文件名字的,方法是取不带目录的模板文件名然后 md5 进行 hash,然后把 hash 出来的字符串取前 16 个字符,后面加上“inc”后缀就成了。
第 4 句是取得完整的缓存文件名。
第 5 距好像是另一个文件名字,就是在缓存文件名字后面再加个后缀“.txt”上面就得到了两个文件名字,但是我们不知道第二个文件名字干什么用的,再继续往下看咯啊的
代码吧。
this-gtCacheFile ckfullfilethis-gtTempMkTime filemtimefilenameiffile_existsckfullfilefile_existsckfullfile_t return false第 1 句就指定了当前模板的缓存文件第 2 句读取了文件的最后修改时间,设置了一个什么时间的属性,现在还不大明白。
接下来的 if 语句就是如果找不到模板的两个缓存文件(就是上面组合出来的两个文件),就返回 false 让 LoadTemplate 方法解析模板去。
我们假设模板的缓存文件都有,继续看
代码。
下面
代码段写了注释,就是检测模板最后更新时间,
代码很简单,就是打开我们前面说的那个ckfullfile_t 变量指定的 txt 文件,读内容,然后把内容和缓存修改时间比较,原来.txt 文件是用来保存缓存文件的保存时间的。
如果时间不一致则就返回 false 让 LoadTemplate 方法解析模板去。
我们假定缓存有效,那么就可以继续了。
缓存有效就会把缓存文件包含进来。
这块就要根据缓存文件来具体分析了,所以,我们这里假定载入的是 index.htm 模板吧,在 tplcache 里面找到 index.htm 开头,后缀为 inc 的文件,打开。
我们这里节选一部分:z0Arrayquotglobalquotquotquot236264z04namequotcfg_soft_langquotz1Arrayquotglobalquotquotquot277303z14namequotcfg_webnamequotz2Arrayquotglobalquotquotquot347377z24namequotcfg_descriptionquotz3Arrayquotglobalquotquotquot414441z34namequotcfg_keywordsquot……再回到我们的 LoadCache 方法里面。
前面说到 include 了模板缓存文件,然后,下面的 if 语句判断的是缓存文件里面的信息数组“z”是否正常,如果正常就进行来个 foreach 循环,这个 foreach 很重要。
我们来看看
代码。
foreachz as kgtv this-gtCount ctag new DedeTAg ctag-gtCAttribute new DedeAttribute ctag-gtIsReplace FALSE ctag-gtTagName v0 ctag-gtInnerText v1 ctag-gtStartPos v2 ctag-gtEndPos v3 ctag-gtTagValue ctag-gtTagID k ifissetv4 ampamp is_arrayv4 i 0 foreachv4 as kgtv ctag-gtCAttribute-gtCount ctag-gtCAttribute-gtItemskv this-gtCTagsthis-gtCount ctag这是个遍历缓存信息数组,然后每个z 数组的元素,都生成一个 DedeTAg 对象,并把z 数组元素的一些信息赋给 DedeTAg 对象,我们经过看这段源
代码,发现, 数组元素中0 是标签名称 z (TagName) 1 是内部文本InnerText, 是开始位置 , .
上一篇:
Java毕设论文+源代码+答辩演示文稿+外文文献及翻译
下一篇:
宽量程高精度电池数据采集系统的研究