织梦获取已安装模块信息的函数GetModuleList()分析

admin2023-01-181129

函数名: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文件,你会发现这个文件这个就是我们刚刚安装的一个小说了。

网友评论