织梦频道模型单元类__construct($cid,$aid=0)源码分析教程
所在类文件:include/channelunit.class.php
功能:这个构造函数的功能是返回当前对象里面的数组$this->ChannelFields,这个数组是一个二维数组,这样说的话,不够准确,因为,这个数组里面还有一个对象,对象里面包含一个数组。等我们把代码分析完后,我们再把这个构造函数被调用后的结果打印出来,这样就很好理解了,如果现在直接给你打印出来,连代码都不知道,效果不好。
既然是频道模型单元类里面的构造函数那么,这个构造函数一定与频道模型表有关,是的,这个构造函数初始化的目的就是把频道模型表里面的字段,以及在频道模型表#@__channeltype里面的字段fieldset值,一块遍历出来放在数组$this->ChannelFields里面,以备后面实例化这个类的php文件使用。
知道了上面大概的功能后,我们就可以分析一下这个构造函数的源代码了。
前几行代码就是初始化,不用解释,但是,要注意里面的$this->dsql = $GLOBALS['dsql'];这一句,这句代码的意思是,把全局变量赋给当前dsql,这个全局变量其实就是数据库连接信息,这个我们在后面的教程里会再一次详细解释,这里先暂时一放。
接下来就是查询模型表中的所有字段,放入到一组数组$this->ChannelInfos里面,此时,它还是一个一维数组,代码如下所示:
下面的代码就是处理字段fieldset值了,我们先把频道模型数据库表#@__channeltype里面查看一下这个字段值,如下图所示。
这里我是以文章模型为例子截的图,字段fieldset值就是我们在后台增加的附加表字段,如下图所示。
这些字段其实是存放在附加表#@__addonarctile(当然,这里是以文章模型为例子),查看一下附加表如下图所示。
现在我们知道了附加表字段fieldset值,这个值就是在后台添加字段后,生成的,这个值是存放在频道模型表中的。也就是说我们在后台添加一个字段,织梦程序会在频道模型和附加表中增加相应内容。
接着看代码,实例化静态模板引擎,设置命名空间,然后,载入模板字段串,也就是fieldset值。
接下来就是处理这些模板字符串了。
foreach遍历模型字符串,在这里面设置一个标志位$tnames[$tname] = 1;若这个已经设置了,说明这个标记程序已经解析过了,就终止循环。
接着执行代码,把所有的标记放入到$this->AllFieldNames里面,当遍历到一个标记后,判断这个里面是否为空,若不空则加上逗号,否则则说明是第一个直接加入到这个变量里面。
然后,判断标记属性是否为空,若不为空,则把这个属性数组放入到数组$this->ChannelFields里面,此时,这个数组由一维数组就变成了二维数组了,代码如下所示。
然后,把当前标记的value值设置为空,把当前的底层模板进行赋值,代码如下:
$this->ChannelFields[$tname]['value'] = ''; $this->ChannelFields[$tname]['innertext'] = $ctag->GetInnerText();
通过这二个也可以看出$this->Channelfields也是一个二维数组。
判断$this->ChannelFields[$tname]['itemname']值,也就是下面标签里面的itemname的值是不是空,若为空,则把louhao作为这个itemname的值。
<field:louhao itemname="楼号" autofield="1" notsend="0" type="text" isnull="true" islist="1" default="" maxlength="250" page=""> </field:louhao>
接下来判断上面标签的page的值,这个是分页,当我们建立一个字段时,这项一般不写,但是,下面这个标签page值就必须有:
<field:body itemname="文章内容" autofield="0" notsend="0" type="htmltext" isnull="true" islist="1" default="" maxlength="" page="split"> </field:body>
这是内容页标签,当然,内容页要分页了,判断代码如下所示:
if($ctag->GetAtt('page')=='split') { $this->SplitPageField = $tname; }
上面的所有分析的代码,不过都是在组装$this->Channelfields数组,现在我打印一下这个数组,如下所示:
ChannelUnit Object ( [ChannelInfos] => Array ( [id] => 1 [nid] => article [typename] => 普通文章 [maintable] => dede_archives [addtable] => dede_addonarticle [addcon] => article_add.php [mancon] => content_list.php [editcon] => article_edit.php [useraddcon] => article_add.php [usermancon] => content_list.php [usereditcon] => article_edit.php [fieldset] => [listfields] => body,qqq,louhao [allfields] => [issystem] => 1 [isshow] => 1 [issend] => 1 [arcsta] => -1 [usertype] => [sendrank] => 10 [isdefault] => 0 [needdes] => 1 [needpic] => 1 [titlename] => 标题 [onlyone] => 0 [dfcid] => 0 ) [ChannelFields] => Array ( [body] => Array ( [itemname] => 织梦基地 [autofield] => 0 [notsend] => 0 [type] => htmltext [isnull] => true [islist] => 1 [default] => [maxlength] => => split [value] => [innertext] => ) [qqq] => Array ( [itemname] => qqq [autofield] => 1 [notsend] => 0 [type] => text [isnull] => true [islist] => 1 [default] => [maxlength] => 250 => [value] => [innertext] => ) [louhao] => Array ( [itemname] => 楼号 [autofield] => 1 [notsend] => 0 [type] => text [isnull] => true [islist] => 1 [default] => [maxlength] => 250 => [value] => [innertext] => ) ) [AllFieldNames] => body,qqq,louhao [ChannelID] => 1 [ArcID] => 6 [dsql] => DedeSql Object ( [linkID] => Resource id #29 [dbHost] => localhost [dbUser] => root [dbPwd] => [dbName] => dedecmsv57gbksp1 [dbPrefix] => dede_ [result] => Array ( [me] => Resource id #52 [one] => Resource id #59 ) www.dedebase.com [queryString] => SELECT tp.*,ch.typename as ctypename,ch.addtable,ch.issystem FROM `dede_arctype` tp left join `dede_channeltype` ch on ch.id=tp.channeltype WHERE tp.id='15' LIMIT 0,1; [parameters] => [isClose] => [safeCheck] => [recordLog] => [isInit] => 1 [pconnect] => ) [SplitPageField] => body )
这个是我打印的 print_r($this->ChannelUnit=new ChannelUnit($arr['channel'], $aid))的结果,从上面可以看出首先是一个对象,然后,里面是一个个数组,最后面的那个sql就是教程刚开始提到的$this->dsql = $GLOBALS['dsql'];这行代码。
想彻底研究织梦系统的朋友,可以仔细研究一下这个打印结果对我们以后,进行织梦二次开发,非常有帮助,现在只是简单地把代码分析好了,当使用的时候,你会发现,这个非常有用。当然,即使不知道这些我们一样可以进行开发,这些是织梦最底层里面的代码了,读一读可以提高我们的编程能力。