织梦标签字段处理函数EvalFunc()

admin2020-01-161062

首先说一下,这个函数是比较底层的,如果不做系统开发,例如,你也想自己开发个像织梦系统这样的系统,那么,这个函数看不看都没有关系,即使你是做织梦二次开发的,这个函数几乎用不用我们去管。当然,如果想研究一下这个代码更好,反正看多了代码只有好处,不像吃饭一样吃多了对身体不好,学的越多能力越强。

这个函数是在织梦静态模板引擎里面的一个比较底层的函数,这个函数,无论在前台还是在后台,看不到它的踪影,但是,这个函数有时候我们会间接的用到它。例如在底层模板中[field:title function="cn_substr(@me,80)"/]我们经常会看到这个函数cn_substr(@me,80),这个函数经常用到,它的功能是截取字段title的值长度,在该标签里面指的是截取标题长度为40个汉字。不一定非截取标题,也可以截取简介、内容等,反正就是截取汉字的或其它符号的长度函数。

那这个截取字符函数与EvalFunc()有什么关系?如果cn_substr(@me,80)在php文件里的话,那么没有什么好说的,就是php里面一个函数,直接调用这个函数就行了,但是,我们现在讲的是在html代码里面,而是在标签里面,所以,直接调用定义的这个函数是不行的,必须经过解析后,才能调用这个值,为什么?在php里面至少@me这个符号,php它就不知道是什么,因为,这个是织梦官方自己定义的,所以,这就要求把@me这个符号进行解析一下,解析成php能够识别的代码,然后,执行代码。

从上面我们就可以看出Evalfunc()其实是函数cn_substr(@me,80)的底层解析函数,也就是把这个函数里面的@me等符号替换成php能够执行的内容。当然,这个函数EvalFunc()不仅仅是cn_substr(@me,80)函数的解析函数,而是所有在标签里面的使用的函数的底层解析函数。现在知道了为什么在标签里写上函数就可以执行了吧?就是因为EvalFunc()这个函数的作用。

函数名:EvalFunc($fieldvalue,$functionname,&$refObj)

参数: $fieldvalue  字段值;$functionname  函数名称;object  $refObj  隶属对象

返回值:返回解析后的字符串

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

代码分析开始:

      function EvalFunc($fieldvalue,$functionname,&$refObj)
    {
        $DedeFieldValue = $fieldvalue;
        $functionname = str_replace("{\"","[\"",$functionname);
        $functionname = str_replace("\"}","\"]",$functionname);
        $functionname = preg_replace("/'@me'|\"@me\"|@me/i",'$DedeFieldValue',$functionname);
        $functionname = "\$DedeFieldValue = ".$functionname;
        @eval($functionname.";"); //or die("<xmp>$functionname</xmp>");
        if(empty($DedeFieldValue))
        {
            return '';
        }
        else
        {
            return $DedeFieldValue;
        }
    }

重新解释一下参数:第一个参数是字段值,也就是上面提到底层模板[field:title function="cn_substr(@me,80)"] 里面的title的值,第二个参数指的是函数的名称,即cn_substr(@me,80),前面的双引号等符号都没有,第三个参数是隶属对象,这里指的是标记的对象,因为,这个底层模板会被模板引擎解析成一个类似下面的对象:

DedeTag Object
(
    [IsReplace] => 1
    [TagName] => title
    [InnerText] =>
    [StartPos] => 30
    [EndPos] => 44
    [CAttribute] => DedeAttribute Object
        (
            [Count] => -1
            [Items] =>
        )

    [TagValue] => 浅谈XHTML(可扩展HTML)标准中CDATA
    [TagID] => 1
)

这个隶属对象指的就是这个解析后的对象。这一点要弄明白了,那么,你对这个标记就理解了。如果还不明白请看我分析过的相关的静态模板引擎。

这几个参数知道了,下面的代码其实就简单了。

第一行就不用解释了就是把字段值赋给一个新变量。

第二行:替换标签里面的{\"这个符号为[\",第三行也是符号替换。从这里就可以看出,标签中的函数不一定是在底层模板里面,也有可能在短标记或块标记里面,所以,这里统一把大括号替换成中括号。

第四行:替换函数里面的@me 为字段值,从这时我们可以看出,@me就是一个符号没有什么特殊意义,所以,我们也可以自己定义其它符号代替@me,例如,#me,那么,这样函数cn_substr(#me,80)就变成这样了,从这里可以理解@me的实际含义了吧,他就是一个符号而已,不要想太多。

第五行:定义一个字符串$DedeFieldValue=".$functionname" ,此时,这个字符串如果打印一下的话,就是:

$DedeFieldValue = cn_substr($DedeFieldValue,80)

现在顺利的把标签里面的函数解析完了。

第六行:@eval($functionname.";"); 这个函数作用强大,他可以把字符串作为PHP代码执行,也就是字符串里面的php代码,通过这个函数后,就会被执行。所以,第五行的函数里面的内容就会被执行,相当于调用外部的函数cn_substr($DedeFieldValue,80)函数。只有调用了这个函数,在标签里面的函数才会起作用。

第七行:返回解析后的字符串,也就是从底层模板返回的内容,例如上面举的例子,则返回标题。


网友评论