DedeCMS的模板引擎本质上是一个“替换”工具,它把模板里的特定标记(如 {dede:field.name/})替换成从PHP后端获取的数据,它本身不是一个完整的PHP解释器。

dede模板运行php
(图片来源网络,侵删)

下面我将从最常用、最安全的方法,到更灵活但风险更高的方法,逐一为你介绍。


使用内置的 php 标签(推荐,最常用)

这是DedeCMS官方提供的、在模板中执行简单PHP代码的标准方法,它主要用于一些逻辑判断、简单的变量处理或调用PHP函数。

语法:

{dede:php}
    // 在这里写你的PHP代码
    // 注意:这里的代码是直接执行的,不能使用 echo 等输出语句
    // 必须将需要输出的内容赋值给 $GLOBALS['var'] 或 $arr[] 等变量
{/dede:php}

重要规则:

dede模板运行php
(图片来源网络,侵删)
  1. 不能直接使用 echoprint:模板引擎在解析时会直接输出 echo 的内容,这可能会破坏模板结构,你必须将结果赋值给一个变量。
  2. 输出赋值:将你需要显示在模板上的PHP代码执行结果,赋值给 $GLOBALS 变量或 $arr 数组。
  3. 变量调用:如果你需要将结果赋值给一个变量以便后续使用,可以使用 $GLOBALS['your_var_name'] = 'your_value';

场景示例 1:执行一段代码并输出结果

假设你想在模板中显示当前服务器的PHP版本。

模板代码 (index.htm):

<h3>服务器信息</h3>
<p>当前PHP版本是: {dede:php}$GLOBALS['php_version'] = phpversion();{/dede:php} [field:php_version/]</p>

说明:

  • {dede:php}...{/dede:php} 之间的代码 phpversion() 会执行,获取PHP版本号。
  • 我们将结果存入 $GLOBALS['php_version']
  • [field:php_version/] 是DedeCMS的普通字段标签,它会自动去 $GLOBALS 中查找 php_version 这个变量并显示其内容。

场景示例 2:循环和条件判断

假设你想循环输出一个数组。

模板代码 (index.htm):

<h3>产品列表</h3>
<ul>
{dede:php}
    $products = array('苹果', '香蕉', '橙子');
    $GLOBALS['product_list'] = '';
    foreach ($products as $product) {
        $GLOBALS['product_list'] .= "<li>" . $product . "</li>";
    }
{/dede:php}
    [field:product_list/]
</ul>

说明:

  • 我们定义了一个数组 $products
  • 通过 foreach 循环,将每个产品格式化为 <li> 标签,并拼接到 $GLOBALS['product_list'] 字符串中。
  • 使用 [field:product_list/] 将整个拼接好的HTML字符串输出到页面上。

使用 global 标签(适用于在循环外赋值)

{dede:php} 标签在循环标签(如 {dede:arclist})内部使用时可能会有些限制,如果你想在循环外定义一些变量,可以在循环前使用 {dede:global}

语法:

{dede:global name='your_var_name'}your_value{/dede:global}

或者

{dede:global name='your_var_name'/}  // 用于赋值空值或由PHP代码赋值

场景示例: 假设你想定义一个网站标题,这个标题是通过PHP函数动态生成的。

模板代码 (head.htm):

或者,如果这个变量在模板的其他地方被使用:

{dede:global name='dynamic_title'/}
<!-- 在页脚使用 -->
<footer>{dede:global name='dynamic_title/'} 版权所有</footer>

使用自定义函数(最灵活、最推荐)

当你的PHP代码逻辑比较复杂,或者想在多个模板中复用时,最佳实践是在DedeCMS的后端创建一个自定义函数,然后在模板中调用这个函数。

步骤:

  1. 创建自定义函数文件: 在 include/extend.func.php 文件中添加你的PHP函数,这个文件是专门用来存放用户自定义函数的,升级DedeCMS时不会被覆盖。

    include/extend.func.php 文件内容:

    <?php
    // 如果文件不存在,则创建它
    if(!file_exists(DEDEROOT.'/include/extend.func.php')) {
        $fp = fopen(DEDEROOT.'/include/extend.func.php', 'w');
        fwrite($fp, '<?php\r\n\r\n?>');
        fclose($fp);
    }
    // 添加你的自定义函数
    if(!function_exists('getRandomProducts')) {
        function getRandomProducts($num = 3) {
            // 这里写你的复杂逻辑,比如查询数据库
            global $dsql;
            $result = $dsql->GetOne("SELECT COUNT(*) AS total FROM `dede_archives` WHERE arctypeid = 1");
            $total = $result['total'];
            // 随机获取ID
            $random_ids = array();
            for ($i = 0; $i < $num; $i++) {
                $random_ids[] = mt_rand(1, $total);
            }
            $random_ids_str = implode(',', $random_ids);
            // 查询随机产品
            $query = "SELECT id, title FROM `dede_archives` WHERE id IN ($random_ids_str) LIMIT $num";
            $dsql->Execute('me',$query);
            $products = array();
            while($row = $dsql->GetArray('me')) {
                $products[] = $row;
            }
            return $products;
        }
    }
    ?>
  2. 在模板中调用自定义函数: 使用DedeCMS的 function 标签来调用你刚刚创建的函数。

    模板代码 (index.htm):

    <h3>随机推荐产品</h3>
    <ul>
    {dede:function name='getRandomProducts' num='5'}
        <li><a href="[field:id runphp='yes']global $cfg_cmspath; @me = $cfg_cmsurl.'/plus/view.php?aid='.$;[/field:id]">[field:title/]</a></li>
    {/dede:function}
    </ul>

    说明:

    • {dede:function name='getRandomProducts' num='5'} 会调用 getRandomProducts(5) 函数。
    • 函数返回的数组会自动被 {dede:function} 标签循环输出。
    • 循环内部,你可以像使用 {dede:arclist} 一样使用 [field:title/][field:id/] 等标签来访问数组中每个元素的键。

直接嵌入PHP代码(极度不推荐,有安全风险)

在某些非常特殊的情况下,你可能会看到有人在模板文件(.htm)中直接写 <?php ... ?> 代码。

示例:

<h3>危险的做法!</h3>
<?php
    $result = mysql_query("SELECT * FROM dede_archives");
    while($row = mysql_fetch_array($result)) {
        echo "<p>" . $row['title'] . "</p>";
    }
?>

为什么强烈不推荐?

  1. 安全漏洞:这是最严重的问题,如果模板文件上传或保存时处理不当,恶意用户可以上传包含恶意PHP代码的模板文件,从而获取网站控制权(Webshell)。
  2. 破坏模板结构:直接使用 echo 会和DedeCMS的模板引擎产生冲突,导致页面布局错乱。
  3. 失去模板的意义:这样做就完全绕过了DedeCMS的模板机制,使得网站维护变得非常困难,也失去了DedeCMS的很多便捷功能。

除非你100%确定你在做什么,并且了解所有风险,否则永远不要使用这种方法。


总结与最佳实践

方法 语法 优点 缺点 适用场景
内置php {dede:php}...{/dede:php} 官方支持,简单直接,适合简单逻辑 不能直接echo,复杂代码写起来混乱 简单变量处理、逻辑判断、调用PHP内置函数
global {dede:global name='xxx'} 适合在循环外定义变量 功能相对单一 在模板不同位置共享一个变量值
自定义函数 {dede:function name='myFunc'} 最佳实践,代码复用性强,逻辑与视图分离,安全可控 需要修改PHP文件 复杂的业务逻辑、数据库查询、需要在多处复用的功能
直接嵌入PHP <?php ... ?> 灵活性“最高” 极度危险,破坏模板,易被攻击 几乎没有,仅用于底层开发调试

给你的建议:

  • 优先使用 {dede:php}:对于非常简单的任务,比如获取一个配置项、做一次 if/else 判断,用它最方便。
  • 拥抱自定义函数:对于任何超过3行代码的逻辑,或者你觉得未来可能复用的代码,都请把它写在 include/extend.func.php 中,然后用 {dede:function} 调用,这是最规范、最安全、最易于维护的做法。
  • 绝对不要用 <?php ... ?>:除非你是为了写一个静态HTML文件测试,否则不要在模板文件里直接写PHP代码。