当前位置:主页 > 建站系统 > dedecms >

织梦系统中 @me 实现原理及其使用详细分析

栏目:dedecms 来源: 微信小程序开发网 阅读: 2017-04-15
  相信很多朋友都遇到过织梦系统dedecms里面的 @me 了吧。

 例如,在织梦模板list_article.htm里面,有这样一段使用@me的标签:

[field:array runphp='yes']@me = (empty(@me['litpic']) ? "" : "<a href='{@me['arcurl']}' class='preview'><img src='{@me['litpic']}'/></a>"); [/field:array]


  这段代码是用在底层模板是{dede:list}...{/dede:list}之间的。

  这段底层模板的作用是:判断一下我们在后台发布的内容是不是有缩略图,如果没有的话缩略图就不会显示,否则,在调用处显示缩略图。

  这里面就使用了@me的功能,很多人遇到过但是,真正的理解的人可能不多,一般人都知道@me表示当前值,但是,真正的使用时就不知道如何使用,或是完全不知道做什么用的,一方面是因为织梦官方没有提供教程,另一方面是因为这个用的不多,但是,这个@me用好了,可以做很多事,而且,其实,设计原理也非常好,特别对于做织梦二次开发的或是自己写系统的都很有借鉴意义,有必要详细讲解一下这个@me实现原理及其使用。

  要把@me这个弄明白实现的原理以及它的使用,就要把这个相关的代码研究透彻,源码才是真正理解一个功能的最重要的参考。

  上面这段代码表示使用织梦提供的php接口,从runphp='yes'就可以可以上面这段代码表示运行php接口,如果不理解的话,请接着向下看,不用管什么接口,什么使用php接口,把下面我分析的内容弄明白了就理解了。

@me调用缩略图的实现原理:

  @me['litpic']表示调用织梦dedecms系统主表dede_archvies里面的字段litpic的值,主表如下图所示:



  我们就以文章id为92的记录作为例子,后面在分析代码时我们就以这条数据为例子,并且,请注意这个主表中的每个字段。

   litpic字段对应的值就是我们在后台添加文章时添加的,如下图所示:



  为什么用@me['arcurl']能够调用出织梦主表dede_archvies里面对应的字段litpic的字段值,即缩略图呢?织梦是如何实现的?

  从这里面可以看出@me就像一个数组,在这个数组里面包含了主表dede_archives里面的字段值,类似 array('litpic'=>'/dedecms/uploads/170411/1-1F41111394Q57.png','id'=>"92",'typeid'=>2,.....),真的是这样吗?

  如果@me真的如上面所分析的应当是一个包含主表中字段的数组的话,如果真是这样的话,那我要调用id为92的文章对对应的栏目typeid的值,是不是只需要这样调用@me['typeid']就可以获取到值为2了,如果真这样的话,那太历害了,主表中的字段我就可以完全自由调用。

  这非常类似php里面的一个数组的调用,例如,$$arr = array('a' => 1,'b'=>3,'c'=>4 ),我想调用数组中的b的值,只需要这样调用 $$arr['b'] 即可获取到键b对应的值为3。

  真的如上面所分析的@me就是一个包含主表中字面的数组吗? 请看下面的分析。

  我们知道织梦生成html代码是通过织梦的模板引擎来实现的,也就是由/include/dedetag.class.php静态模板引擎来实现的。

  那上面这段代码:
[field:array runphp='yes']@me = (empty(@me['litpic']) ? "" : "<a href='{@me['arcurl']}' class='preview'><img src='{@me['litpic']}'/></a>"); [/field:array]


  也是由文件dedetag.class.php来处理的,在这个文件里面找到这样一个函数:RunPHP(&$$refObj, $$i)

  函数RunPHP(&$$refObj, $$i)的作用就是解释上面的这段代码。

    function RunPHP(&$$refObj, $$i)
    {
        $$DedeMeValue = $$phpcode = '';
        if($$refObj->GetAtt('source')=='value')
        {
            $$phpcode = $$this->CTags[$$i]->TagValue;
        }
        else
        {
            $$DedeMeValue = $$this->CTags[$$i]->TagValue;
            $$phpcode = $$refObj->GetInnerText();
            
        }
        $$phpcode = preg_replace("/'@me'|\"@me\"|@me/i", '$$DedeMeValue', $$phpcode);
        @eval($$phpcode); //or die("<xmp>$$phpcode</xmp>");

        $$this->CTags[$$i]->TagValue = $$DedeMeValue;
        $$this->CTags[$$i]->IsReplace = TRUE;
    }


  在这个函数里面一般都是执行else里面的代码,即:

            $$DedeMeValue = $$this->CTags[$$i]->TagValue;
            $$phpcode = $$refObj->GetInnerText();


  我们来分析一下这两行是做什么的。

  $$this->CTags[$$i]->TagValue:这行代码表示获取当前id(假设以文章id值为92作为例子)为92的文章对应主表里面的字段键值对,也就是一个如下所示的数组$$DedeMeValue:

array (
  'id' => string '92' (length=2)
  'typeid' => string '2' (length=1)
  'typeid2' => string '0' (length=1)
  'sortrank' => string '1491881978' (length=10)
  'flag' => string 'p' (length=1)
  'ismake' => string '0' (length=1)
  'channel' => string '1' (length=1)
  'arcrank' => string '0' (length=1)
  'click' => string '170' (length=3)
  'money' => string '0' (length=1)
  'title' => string 'DedeCMS V5.6 开发日志及新建议提交贴' (length=46)
  'shorttitle' => string '' (length=0)
  'color' => string '' (length=0)
  'writer' => string '织梦官方' (length=12)
  'source' => string '织梦官方' (length=12)
  'litpic' => string '/dedecms/uploads/170411/1-1F41111394Q57.png' (length=43)
 
)


$$refObj->GetInnerText():表示获取底层模板[field:array runphp='yes']和[/field:array]之间的内容,

  也就是获取的内容是:@me = (empty(@me['litpic']) ? "" : "<a href='{@me['arcurl']}' class='preview'><img src='{@me['litpic']}'/></a>");

  把这行内容赋给$$phpcode。

  通过替换函数str_replace,即preg_replace("/'@me'|\"@me\"|@me/i", '$$DedeMeValue', $$phpcode)进行替换。

  因为,$$DedeMeValue是上面列出id为92的数组,通过上面的替换函数,把@me全部替换为$$DedeMeValue。

  替换后的结果:
$$DedeMeValue = (empty($$DedeMeValue['litpic']) ? "" : "<a href='{$$DedeMeValue['arcurl']}' class='preview'><img src='{$$DedeMeValue['litpic']}'/></a>");


  $$DedeMeValue['litpic']结果是什么,这不正是后台添加到主表中的缩略图,即主表中litpic对应的值:/dedecms/uploads/170411/1-1F41111394Q57.png

  所以底层模板中empty(@me['litpic'])意思是判断一下缩略图是否为空,若不为空则调出一个缩略图来。

  通过上面的分析可以知道,那如果我想调用id=92对应的栏目id只需要使用 @me['typeid']即可,不防测试一下。

如下图所示:

 
  我修改list_article.htm模板里面的底层模板,然后,生成一下看看id为92的文章对应的栏目是不是正确。

  生成一下结果如下图所示:


  即@me['typeid']的值为2,看看数据库表对应的值是不是为2,如下图所示:




  果然是2,成功搞定。

总结:

  从上面的分析可以看出@me其实就是主表中字段及其值构成的一个数组,您可以使用@me来调用主表中的任何字段值,例如,调用某一篇文章的的“作者”,使用 @me['writer']调用即可。

  从这里您可以学到@me有多灵活了吧,这种思想可以帮助我们做织梦二次开发,或是自己开发一个系统,或是在学习php框架后来自己开发类似的功能。

  上面就是分析的@me实现原理及其使用,看了这么多应当彻底理解了@me了吧。