织梦获取已安装模块信息的函数GetModuleList()分析
函数名:GetModuleList($moduletype='')
函数功能:获取织梦系统已经安装模块的基本信息,未安装的将不获得。
函数对数:$moduletype 模块类型
返回值:返回值为一个数组
所在位置:/include/dedemodule.class.php
GetModuleList这个函数获取的是dede已经安装好的模块的基本信息,这里指的是如下图所示的基本信息
也就是.xml模块文件里面的信息:
<baseinfo> name=畅言评论模块 team=织梦团队 time=2014-02-17 email=tianya@desdev.cn url=http://www.dedecms.com hash=606c658db048ea7328ffe1c7ae2a732f indexname= indexurl= ismember=0 autosetup=1 autodel=1 lang=gb2312 moduletype=soft </baseinfo>
现在我们知道这个函数是做什么了,我们就分析一下这个函数的具体代码。
function GetModuleList($moduletype='') { if(is_array($this->modules)) return $this->modules; $dh = dir($this->modulesPath) or die("没找到模块目录:({$this->modulesPath})!"); $fp = @fopen($this->modulesPath.'/modulescache.php','w') or die('读取文件权限出错,目录文件'.$this->modulesPath.'/modulescache.php不可写!'); fwrite($fp, "<"."?php\r\n"); fwrite($fp, "global \$allmodules;\r\n"); while($filename = $dh->read()) { if(preg_match("/\.xml$/i", $filename)) { $minfos = $this->GetModuleInfo(str_replace('.xml','',$filename)); if(isset($minfos['moduletype']) && $moduletype!='' && $moduletype!=$minfos['moduletype']) { continue; } if($minfos['hash']!='') { $this->modules[$minfos['hash']] = $minfos; fwrite($fp, ' 第一行代码:条件判断当前的变量$modules是不是一个数组,若是则返回这个数组。 第二行代码:通过函数dir($this->modulesPath)来打开路径为/data/mudule/的目录,注意这个dir()函数,它返回的是一个“对象”,而且,这个函数里面有三个方法:read() , rewind() 以及 close()。若成功,则该函数返回一个目录流,否则返回 false 以及一个 error。 我们举一个例子来测试一下这个函数以及它里面的方法。因为,这个函数在打开目录时经常用到,所以,这里来测试一下,以便于大家理解。 建立文件test.php,建立一个目录在这个目录里面放几个txt文件,gif图片,如下图所示。 然后,在test.php文件里写上如下代码: [code]<?php $dir = dir("test"); while (($file = $dir->read()) !== false) { echo $file . "<br />"; } $dir->close(); ?>
打印一下
从上面的结果我们可以看出dir()函数获得到了一个对象,通过$dir->read()调用后,得到的是一个一个的字符串,这些字符串,除了前二个符号外,其它都是在目录test里面的内容。
回来我们原来的函数,接着分析代码。
实际上本函数是操作的位于/data/module/目录下的文件modulescache.php,函数是把module目录下面的modulescache.php缓存文件遍历出来放到数组里面,以备后面的调用它的程序使用,接下来就是通过函数fopen()打开这个文件,代码是:@fopen($this->modulesPath.'/modulescache.php','w')。
然后,在这个文件里写入php开始符号:"<?php " ,然后,写入"global $allmodules"。
通过while($filename = $dh->read())遍历module目录下面.xml文件。
条件判断一下通过$db->read()读取的内容是不是.xml文件,因为,在module目录下面有很多文件,其中有.txt为后缀的文件,也有.php为后缀的文件,所以,这里要遍历一下。若取出的一个文件以.xml为后缀,说明是我们要找到文件,然后,接着执行下面的代码。
获取这个文件的基本信息,这里用了GetModuleinfo(str_replace('.xml','',$filename))这行代码,因为,这个函数的参数是一个hash码,所以,这里通过函数str_replace()把.xml去掉后,就是一个hash码了。
判断若参数$moduletype不空,并且,这个类型与获取的这个.xml文件里面的类型不相同,则说明,这个.xml文件不是我们想要的,这里还有一个是且的关系的,必须是已经设置了这个.xml里面的moduletype值,例如,畅言里面的moduletype值等于soft。若这三个条件同时成立,则continue;
如果hash值不为空,那就把这个hash编码所在的模块文件里面的整个基本信息,一起存放到数组$this->modules里面,然后,再把下面这一行:
$GLOBALS['allmodules']['0a7bea5dbe571d35def883cbec796437']='0a7bea5dbe571d35def883cbec796437.xml';
覆盖方式写入到模块缓存文件modulescache.php 里面,也就是说这个函数同时做二件事,一是把这个.xml里面的基本信息存放到数组$this->modules里面,二是把0a7bea5dbe571d35def883cbec796437.xml这个文件写入到缓存模块文件里面。
然后,关闭文件,返回数组$this->modules,这个函数偷偷做了第二件事,并没有返回任何信息。
目前,我的系统安装了8模块,现克们就测试一下,我安装一个“小说”模块,如果我们再打开moduelscache.php文件,我们会发现这个文件里面多了一行代码:
$GLOBALS['allmodules']['7badb72a3ff79af2a7112beee60cb970']='7badb72a3ff79af2a7112beee60cb970.xml';
我们打开这个.xml文件,你会发现这个文件这个就是我们刚刚安装的一个小说了。