runphp 是 DedeCMS 模板引擎一个非常强大且核心的功能,它允许你在模板文件(通常是 .htm 文件)中直接嵌入 PHP 代码,从而实现复杂的逻辑判断、数据处理和动态内容生成。

dede 模板 runphp
(图片来源网络,侵删)

runphp 的基本语法

runphp 主要通过两个核心的底层函数实现:GetOnePara()array()

{dede:field name='phpcode' function='GetOnePara(@me, "code")' /}

这是最常用、最标准的 runphp 写法。

  • {dede:field ...}: 这是 DedeCMS 的字段调用标签。
  • name='phpcode': 这里 phpcode 是一个虚拟字段名,它本身并不存在于数据库中,我们只是借用这个标签的结构来承载我们的 PHP 代码。
  • function='GetOnePara(@me, "code")': 这是关键部分。
    • function: 指定要对字段值执行的函数。
    • GetOnePara(): 这是 DedeCMS 的一个底层函数,用于处理 @me 变量并返回结果。
    • @me: 这是一个特殊的变量,代表当前字段的原始值,在这个例子里,因为我们用的是虚拟字段,@me 初始值为空 。
    • "code": 这是传递给 GetOnePara 函数的第二个参数,它告诉函数,我们接下来要执行的是一段 PHP 代码。

代码块如何写? 紧跟在标签后面的 phpcode 字段值,就是你想要执行的 PHP 代码。注意:这里的代码块必须使用双引号 包裹。

示例:

dede 模板 runphp
(图片来源网络,侵删)
{dede:field name='phpcode' function='GetOnePara(@me, "
    $a = 10;
    $b = 20;
    $c = $a + $b;
    echo $c;
")' /}

输出结果:

30

{dede:array name='phpcode'} ... {/dede:array}

这种写法适用于需要执行多行 PHP 代码,并且希望代码块结构更清晰的情况,它会把 PHP 代码块作为 array 标签的内容。

语法结构:

{dede:array name='phpcode'}
    // 你的 PHP 代码写在这里
{/dede:array}

示例:

dede 模板 runphp
(图片来源网络,侵删)
{dede:array name='phpcode'}
    $str = "Hello, DedeCMS!";
    $str .= " This is a test.";
    echo $str;
{/dede:array}

输出结果:

Hello, DedeCMS! This is a test.

runphp 的核心应用场景

runphp 的真正威力在于处理数据,尤其是在列表页和内容页中。

场景1:列表页 - 处理文章摘要/描述

字段 description 存储的是一段长文本,我们想在列表页只显示前 50 个字符,并在末尾加上 "..."。

不使用 runphp 的做法(笨拙): 需要在后台手动截取,或者修改程序。

使用 runphp 的做法(灵活):

在列表模板 list_articel.htm 中:

[field:description function='GetOnePara(@me, "
    if(strlen(@me) > 50){
        @me = cn_substr(@me, 50) . '...';
    }
")'/]

代码解析:

  • @me: @me 代表当前文章的 description 字段的原始值。
  • strlen(@me): 获取摘要的长度。
  • cn_substr(@me, 50): 这是 DedeCMS 提供的函数,用于安全地截取中文字符串,避免乱码,它比 PHP 原生的 substr 更适合处理中文。
  • @me = ...: 将处理后的结果重新赋值给 @me,DedeCMS 会输出 @me 的最终值。

场景2:内容页 - 动态生成文章链接

假设你的文章有不同的类型,存放在不同的栏目,并且它们的链接规则不同。

  • 普通文章:/a/2025/123.html
  • 产品文章:/products/123.html

我们可以通过文章的一个自定义字段(typeid)来判断。 模板 article_articel.htm 中:**

假设我们有一个自定义字段 linktype,值为 1 表示普通文章,值为 2 表示产品文章。

{dede:field name='phpcode' function='GetOnePara(@me, "
    $linktype = @me; // 先获取当前文章的linktype值
    $aid = @me; // 注意:在内容页,@me默认是文章ID,所以这里可以直接用
    if($linktype == 1){
        @me = '/a/'.date('Ym', @me).$aid.'.html';
    } elseif($linktype == 2){
        @me = '/products/'.$aid.'.html';
    } else {
        @me = '/a/'.$aid.'.html'; // 默认链接
    }
")'/}

注意: 上面这个例子是一个简化的逻辑,在实际内容页中,获取文章ID和栏目ID有更规范的方式,{dede:field.id/}{dede:fieldtypeid/},这个例子只是为了演示 runphp 的条件判断能力。

场景3:内容页 - 处理时间格式

默认的时间格式可能不满足需求,比如想显示为 "2025年10月27日 星期五"。 模板中:**

发布时间:{dede:field name='pubdate' function='GetOnePara(@me, "
    @me = date('Y年m月d日 星期w', @me);
    $week = array('日','一','二','三','四','五','六');
    @me = str_replace('星期w', '星期'.$week[date('w', @me)], @me);
")'/}

更简单的写法(推荐): DedeCMS 已经内置了 MyDate 函数来处理日期格式,runphp 不是最佳选择,除非有更复杂的逻辑,但如果要用 runphp,上面的代码是可行的。


runphp 中可用的函数和变量

runphp 代码块中,你可以使用:

  1. PHP 原生函数:如 strlen(), substr(), explode(), array() 等。
  2. DedeCMS 全局函数
    • cn_substr($string, $length): 安全截取中文字符串。
    • MyDate($format, $timestamp): 格式化日期时间。
    • GetMkTime($dtime): 将日期字符串转为时间戳。
    • 等等。
  3. DedeCMS 全局变量
    • @me: 当前字段的值。
    • $cfg_系列变量: 如 $cfg_cmspath (CMS路径), $cfg_indexurl (首页URL) 等。
    • $dsql: DedeCMS 的数据库操作对象,可以直接用来查询数据库(不推荐在模板中直接查询,性能差)。

重要注意事项与最佳实践

  1. 性能问题

    • 避免在循环中执行复杂查询runphp 会在模板渲染时执行,如果你在列表页的 {dede:list} 循环里对每篇文章都执行一次 runphprunphp 内部有数据库查询,这会导致页面加载极慢,因为 N 次循环就会执行 N 次数据库查询。
    • 替代方案:对于需要额外数据的情况,最佳实践是在PHP 程序文件(如 include/inc_arcpart_view.php)中通过 Join 查询一次性获取所有需要的数据,然后将处理好的数据通过 ParseTempletsFirst() 等方法赋值给模板变量,这样只需要一次数据库查询。
  2. 安全性问题

    • runphp 是一个“后门”,因为它允许在模板中执行任意 PHP 代码。
    • 不要在面向公众的模板系统中过度使用,特别是如果网站允许用户上传或修改模板。
    • 在管理后台,默认情况下 runphp 可能是关闭的,你需要开启它:进入 系统 -> 系统基本参数 -> 核心设置,找到 “模板引擎禁用标签”,确保里面没有 php,如果禁用了 phprunphp 也将无法工作。
  3. 代码可读性

    • 对于非常复杂的逻辑,runphp 会让模板文件变得难以阅读和维护。
    • 遵循“模板只负责展示,逻辑交给程序”的原则,如果逻辑过于复杂,应该考虑修改程序文件,而不是把所有逻辑都塞进模板里。
  4. 调试

    • runphp 中的 PHP 代码出错时,错误信息可能不会直接显示在页面上,或者被 DedeCMS 的错误处理机制吞掉。
    • 调试技巧:使用 echoprint_r 来输出中间变量,看看代码执行到哪一步,变量的值是什么。
    • echo "Debug: Here!"; 或者 print_r($my_array);

runphp 是 DedeCMS 提供给开发者的一个“瑞士军刀”,它极大地增强了模板的灵活性。

  • 优点:快速实现简单的逻辑处理,无需修改程序文件,对非程序员友好。
  • 缺点:可能影响性能,降低代码可维护性,存在安全风险。

最佳实践建议

  • 多用:用于简单的字符串处理、条件判断、格式化。
  • 慎用:避免在循环中进行数据库查询。
  • 少用:将复杂的业务逻辑留给 PHP 程序文件。

掌握 runphp 能让你在修改和定制 DedeCMS 网站时事半功倍。