织梦自由列表类构造函数__construct($fid)详解
我们知道文档类构造函数是比较复杂的,这个自由列表的代码看上去没有文档类构造函数代码多,但是,这个一点也不比文档简单,主要是这个自由列表构造函数实例化了多个类,一旦实例化一个类,就有可能牵涉到多个类文件,所以,从这点来说这个构造函数不简单。但是,这些实例化的后的对象在构造函数里面又没有直接使用,这样又使得这个构造函数比较简单。
我们先看一下自由列表是做什么的,自由列表标签为:{dede:freelist/}非常简单,它的功能根{dede:article}{/dede:article}几乎完全一样,但是,自由列表又有一个{dede:article}所不具备的功能就是可以分页,有很多网站看上去像是博客,其实,是织梦做的,就是用的这个自由列表,关于其它的自由列表的应用就不多。
因为,这个自由列表比较生僻,所以,这里织梦基地把自由列表的数据库贴出来,以备我们分析代码研究之用。
自由列表数据库表#@__freelist:
然后,我在后台建立一个自由列表,以备代码分析使用。
代码分析开始:
首先,把当前的实例化自由列表类时的自由列表id赋给$this->FreeID,然后,实例化一个栏目连接类,这个类虽然,在这里实例化了,但是,在构造函数里面没有使用,这个要在对象里面的其它方法里面使用,本来构造函数就是初始化的,并不一定去直接做什么工作,只有必须要做的才在构造函数里面去做,所以,这是非常正常的。
初始化数据库对象这个是必须的,每一个类只要操作数据库就必须初始化这个:
$this->dsql = $dsql;
设置主表为:#@__archives.
查询aid为$fid的自由列表所有字段的一条记录,这里的$fid是自由列表的id值,也就是我们在后台增加自由列表后的id值,这个在实例化自由列表类时,直接传这个值。
代码:
$this->FLInfos = $this->dsql->GetOne("SELECT * FROM `#@__freelist` WHERE aid='$fid' ");
实际上这个自由列表构造函数的主要功能就是把自由列表中的字段,以及listtag里面的标签取出来,放到$this->FLInfos里面。
处理listtag里面的标签:
这个listtag里面的内容如下所示:
{dede:list pagesize='30' col='1' titlelen='60' orderby='pubdate' orderway='desc' typeid='1' channel='1' } <li>[field:imglink/] [field:textlink/] <span class=info><small>日期:</small>[field:pubdate function="getdatemk(@me)"/] <small>点击:</small>[field:click/] <small>好评:</small>[field:scores/] </span> <p class=intro>[field:description/]...</p></li> {/dede:list}
现在就处理这个标签,要处理标签当然得使用织梦静态模反引擎了,所以,实例化模板引擎类,设置命名空间,载入这个标签进行处理。
在处理这个过程中,有一行代码是我们必须了解的:
$this->ListObj = $ndtp->GetTag('list')
这里面的函数$ndt->GetTag('list')指的是:获得list的CTag数据类,是list的对象,也就是上面标签的Ctag对象,因为,CTags是一个标记对象的数组,而CTag则是其中一个对象,通过函数GetTag('list')执行后,得到的就是这个list标记对象,我把它打印出来如下所示:
[ListObj] => DedeTag Object ( [IsReplace] => [TagName] => list [InnerText] => [field:imglink/] [field:textlink/] 日期:[field:pubdate function="getdatemk(@me)"/] 点击:[field:click/] 好评:[field:scores/] [field:description/]... [StartPos] => 0 [EndPos] => 372 [CAttribute] => DedeAttribute Object ( [Count] => 6 [Items] => Array ( [pagesize] => 30 [col] => 1 [titlelen] => 60 [orderby] => pubdate [orderway] => desc [typeid] => 1 [channel] => 1 ) ) [TagValue] => [TagID] => 0 )
通过上面我们知道,这不就是上面标签里面的内容吗,只不过通过模板引擎,把标签变成了一个对象,对象里面还包括一个属性对象,属性对象里面又包括一个由属性组成的数组,并且,底层模反都有值。
然后,设置分页大小,获取channelid的值,这些都是从上面的这个listObj对象里面获得的,这就是为什么上面要执行函数$ndtp->GetTag('list')原因了。
全局模板解析:这是相对于上面的局部模板解析,要注意二者区别,只需要看一看模板引擎实例化后的赋给的变量就知道了,第一个是赋给了$ndtp,而接下来的全局模板解析则赋给了$this->dtp,代码对比如下:
$ndtp = new DedeTagParse(); $this->dtp = new DedeTagParse();
这二个写法有区别吗?差别可大了,第一个是解析的模板是自由列的数据库表里面的listtag字段值,而第二个是解析整个自由列表使用的模板list_free.htm里面的标签。
接下来就是设置全局参数,这个没有什么好解释的比较简单,接下来通过$this->ListObj->GetAtt('channel')获得标签里面的模型id,若这个id不为空,则实例化频道模型单元类。
然后,把$GLOBALS['PubFields']数组里面的值遍历出来,放到$this->Fields里面。这个数组是在include/channelunit.class.php 文件里面,已经设置好的。
最后,又实例化了一个视图类,这一个小小的自由列表类,实例化了四个类,可见,这个自由列表用到的类有多大了。
然后,统计一下统计列表里的记录,构造函数结束。
要注意的是,虽然,这里面有很多东西已经实例化或初始化了,但是,在构造函数里并没有用,但这并不代表在这个类中其它的方法没有用,构造函数只是初始化一些设置,能不做的构造函数决不会去做。
结论:以上代码不管多么复杂,多么不好理解,但是,我们只需要记住一点就是,这个构造函数最终目的就是把数组$this->fields给组装起来,当然,还初始化了一些东西。经过这个构造函数,我们得到了一个数组$this->Fields 织梦基地就打印一下,看看这个数组里面到底有什么东西。
Array ( [aid] => 1 [title] => 织梦基地 [position] => 织梦基地 [keywords] => 织梦,织梦cms [description] => 织梦织梦织梦织梦织梦 [phpurl] => /plus [indexurl] => / [templeturl] => /templets [memberurl] => /member [specurl] => /special [indexname] => 主页 [templetdef] => /templets/default )
这不正是我们在后台增加的自由列表的字段值和一些新增加的单元内容吗,这个对应后台的织梦基地增加的自由列表,如下所示。