织梦获得某模块的基本信息函数GetModuleInfo()

admin2019-12-28871

函数名:GetModuleInfo($hash, $ftype='hash')

功能:获得模块的基本信息,这里的基本信息指的是以.xml为后缀的模块里面的标签<baseinfo></baseinfo>之间的模块信息。

所在文件:/include/dedemodule.class.php

这函数一看就可怕,代码那么多,那时候做别的一个实例教程“织梦控制模块安裝步骤深入分析”时,由于启用这一函数,一看代码将我吓了一跳,并非由于过多的代码,只是没有想到调用一个小小的控制模块基本信息,竞然那么多代码。其实只要你研究过织梦系统得话,你就会发现织梦的代码比这一函数代码要更复杂的还有很多。

可是,当你细心去解析里边的代码后,你就会发现实际上,这一代码非常简单,这一函数的代码是那类看起来非常复杂可是里边的逻辑性非常简单,也有一种代码看起来非常简单,可是你去研究里边的代码逻辑性会发觉比较复杂,因此,有时人们不可以只看表面状况,要是人们略微细心深入到程序流程內部,就会发觉也就这样。

函数源代码:

  function GetModuleInfo($hash, $ftype='hash')
    {
        if($ftype=='file') $filename = $hash;

        else if(!empty($this->modulesUrl)) {
            $filename = $this->modulesUrl.$hash.'.xml';
        }else $filename = $this->modulesPath.'/'.$this->GetHashFile($hash);


        $start = 0;
        $minfos = array();
        $minfos['name']=$minfos['team']=$minfos['time']=$minfos['email']=$minfos['url']='';
        $minfos['hash']=$minfos['indexname']=$minfos['indexurl']='';
        $minfos['ismember']=$minfos['autosetup']=$minfos['autodel']=0;
      
        if(empty($this->modulesUrl)){
            $minfos['filesize'] = filesize($filename)/1024;
            $minfos['filesize'] = number_format($minfos['filesize'],2,'.','').' Kb';
        }
        $fp = fopen($filename,'r') or die("文件 {$filename} 不存在或不可读!");
        $n = 0;
        while(!feof($fp))
        {
            $n++;
            if($n > 30) break;
            $line = fgets($fp,256);
            if($start==0)
            {  if(preg_match("/<baseinfo/is",$line)) $start = 1; }
            else
            {
                if(preg_match("/<\/baseinfo/is",$line)) break;
                $line = trim($line);
                list($skey,$svalue) = explode('=',$line);
                $skey = trim($skey);
                $minfos[$skey] = $svalue;
            }
        }
        fclose($fp);

        if(isset($minfos['lang'])) $this->moduleLang = trim($minfos['lang']);
        else $this->moduleLang = 'gbk';

        if($this->sysLang=='gb2312') $this->sysLang = 'gbk';
        if($this->moduleLang=='gb2312') $this->moduleLang = 'gbk';

        if($this->sysLang != $this->moduleLang)
        {
            foreach($minfos as $k=>$v) $minfos[$k] = $this->AppCode($v);
        }

        return $minfos;
    }

我们已经知道了这个函数是获得模块的基本信息的函数,为什么要获取模块?在模块安装时,在文件module-install.php这个里面,程序要把要安装的模块基本信息要插入到数据表#@__sys_module里面,我们每安装一个模块都要把模块的基本信息插入到表里面,所以,这时就要用到这个函数了。

我们先看一下在模块中模块的基本信息,我们找到data/module/里面的以.xml结尾的文件,随便打开一个看一下,模块的基本信息代码如下:

<baseinfo>
name=百度新闻
team=织梦官方
time=2008-11-19
email=admin@dedecms.com
url=www.dedecms.com
hash=0cce60bc0238aa03804682c801584991
indexname=
indexurl=
ismember=0
autosetup=1
autodel=1
lang=gb2312
moduletype=plus
</baseinfo>

也就是对应着我们在后台“模块”——>“模块管理”里面,当我们要安装某一模块时,我们会看到下面的这些信息。

上图中的这些信息就与.xml里面的基本信息相对应。

还与“模块生成向导”——“模块打包”制作时,填写的基本信息对应,因为,这个生成向导生成的文件就是.xml文件,如下图所示。

这个是制作模块安装包,而本教程讲的是安装模块正好方向相板。现在对模块的基本信息应当非常了解了吧,也就是说我们安装模块必须制作基本信息,试想如果你的模块连个基本的信息都没有,那么,安装的站长如何知道你的模块是做什么用的?到底是哪个编码的?都不知道。

好了,对模块基本信息有一个基本了解后,我们就分析这个函数。

第一行代码if($ftype=='file') $filename = $hash;判断文件类型,这一行就非常容易理解了,就是看看我们想获取的模块文件类型是什么,若是file类型,直接把类似的0cce60bc0238aa03804682c801584991赋给变量$filename 。

代码:

else if(!empty($this->modulesUrl)) {
    $filename = $this->modulesUrl.$hash.'.xml';
  }else $filename = $this->modulesPath.'/'.$this->GetHashFile($hash);

这三行代码就是判断模块的url是否存在,其实,这段代码就是查找安装的模块的以xml为后缀的文件,找到后赋给$filename,这个文件就是当前正要安装的。因为,在module-install.php中实例化时,第一个参数为/data/module/,也

就是模块的路径为:$this->modulesPath=/data/module/,所以,现在的这个文件基本路径为:/data/module/fcd00dbb5a51d65aff6c248d221d8bcd.xml,到这里我们知道了是这个模块。

代码:

        if(empty($this->modulesUrl)){
            $minfos['filesize'] = filesize($filename)/1024;
            $minfos['filesize'] = number_format($minfos['filesize'],2,'.','').' Kb';
        }

获取模块的大小,并且通过函数number_format()格式化文件大小,由字节转为kb。
代码:

      $fp = fopen($filename,'r') or die("文件 {$filename} 不存在或不可读!");
        $n = 0;
        while(!feof($fp))
        {
            $n++;
            if($n > 30) break;
            $line = fgets($fp,256);
            if($start==0)
            {  if(preg_match("/<baseinfo/is",$line)) $start = 1; }
            else
            {
                if(preg_match("/<\/baseinfo/is",$line)) break;
                $line = trim($line);
                list($skey,$svalue) = explode('=',$line);
                $skey = trim($skey);
                $minfos[$skey] = $svalue;
            }
        }
        fclose($fp);

已经知道了要安装模块的大小,并且知道文件名是什么,现在就是把这个模块的基本信息一个一个的取出来,因为有多条当然,就要遍历了。

首先打开这个模块,这里以30作为终点,若大于等于30则直接跳出循环。

通过函数fgets()取出一行数据作为一个字符串放到变量$line里面,这里是256个字符长度,当然,我们可不要这个参数,这样的话,就是默认取出1024,可能织梦考虑到性能,只取256个,若一行多了就会截取掉,例如,你的模块名长度大于这个就会截取掉,不过一般的名字没有这么长。

若是$satrt==0,说明是第一次取,所以,用正则匹配找到,基本信息开始处,也就是<baseinfo>标签。并把$start设置为1。

若$start>0则表示开始查找模块基本信息了,先判断一下是不是到了结尾了</baseinfo>若还没有到,当然,目前$start是1,才刚刚开始,所以,还没有到就执行下面的代码,去掉取出的这行前后空格。

然后,通过list($skey,$svalue) = explode('=',$line);这行代码的执行后,例如,以name=百度新闻为例子,执行这行代码后,就得到了$skey="name",$svalue="百度新闻为例子"。

再通过$minfos[$skey] = $svalue这个就把模块的基本信息,都存放到数组里面了。

为了方便大家理解,这就模拟一个$mininfo这个数组如下:

Array (
[url] => http://www.dedebase.com
[email] => tianya@desdev.cn
[time] => 2015-05-20
[team] => 织梦官方
[name] => 百度站内搜索模块
[indexurl] =>
[indexname] =>
[hash] => fcd00dbb5a51d65aff6c248d221d8bcd
[autodel] => 1
[autosetup] => 1
[ismember] => 0
[filesize] => 68.89 Kb
[lang] => gb2312
[moduletype] => templets
)

按正常来理解,现在就已经结束了,因为,我们已经取到了这个模块的基本信息,都放在数组$mininfo这里面了,只要知道了这个数组了,那要取出这个数组里面的值,那么非常容易了。

但是,还有一个问题是:如果你安装的模块编码和你安装的织梦系统的编码不一致,怎么办?还是织梦程序历害,这个已经帮我们想到了,于是,从fclose()这个函数下面的代码开始,就是把模块编码与安装的织梦系统的编码不一致的转成一致的编码,当然,这里是以你安装的系统为准。

在这个函数里面用到了一个转换编码函数AppCode($v),这个函数里面封的是织梦另外封装的编码转换函数:

国标转utf8:gb2utf8

utf8转国标:utf82gb

国标转繁体:gb2big5

繁体转国标:big52gb

AppCode($v)这个函数就是这几个函数转来转去,比较简单,这里就不用多介绍了。

网友评论