织梦获得某模块的基本信息函数GetModuleInfo()
函数名: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)这个函数就是这几个函数转来转去,比较简单,这里就不用多介绍了。