⚠️ 重要安全警告

绝对不要在模板(.htm 文件)中直接使用 PHP 的 include, require, include_once, require_once 等原生函数来引入文件,这样做是极其危险的:

dedecms 在模板里引入php文件夹
(图片来源网络,侵删)
<!-- 错误且危险的做法! -->
{dede:include filename="/php文件夹/myfile.php"/}

或者直接写:

<!-- 错误且危险的做法! -->
<?php include_once('/php文件夹/myfile.php'); ?>

为什么这很危险?

  1. 安全漏洞:DedeCMS 的模板引擎在解析 {dede:} 标签时,如果配置不当或存在漏洞,可能会将 filename 属性的值当作 PHP 代码执行,导致任意文件包含漏洞。
  2. 路径问题:模板引擎处理路径的方式与 PHP 原生函数不同,容易导致路径找不到(No such file or directory)。
  3. 破坏 MVC 架构:DedeCMS 的设计初衷是分离逻辑(PHP)和表现(HTML),直接在模板中写 PHP 逻辑违背了这一原则,使代码难以维护。

推荐方法:使用自定义函数标签(最安全、最规范)

这是 DedeCMS 官方推荐且最安全的方式,其核心思想是: 在 PHP 文件夹中创建你的 PHP 逻辑文件,然后创建一个自定义标签函数来调用这个 PHP 文件,最后在模板中使用这个自定义标签。

在 PHP 文件夹中创建你的业务逻辑文件

假设你的 PHP 文件夹是 /include/,你想引入的文件是 get_user_info.php

dedecms 在模板里引入php文件夹
(图片来源网络,侵删)

文件路径:/include/get_user_info.php

这个文件应该只包含纯粹的 PHP 逻辑,并不输出任何 HTML 内容,它通常返回数据(如数组、字符串等)。

<?php
// /include/get_user_info.php
// 假设我们根据用户ID获取用户信息
function getUserInfo($uid = 1) {
    // 这里可以写数据库查询等复杂逻辑
    // 为了演示,我们直接返回一个数组
    $userInfo = [
        'uid' => $uid,
        'name' => '张三',
        'regdate' => date('Y-m-d H:i:s', time() - 86400) // 昨天
    ];
    return $userInfo;
}
// 调用函数并获取数据
$uid = isset($uid) ? intval($uid) : 1;
$data = getUserInfo($uid);
// 将数据返回给调用者
// 注意:这里不 echo,而是 return
return $data;
?>

创建一个自定义标签函数

你需要修改一个 DedeCMS 的核心文件来注册你的自定义标签,这个文件是 /include/extend.func.php

如果这个文件不存在,请在 /include/ 目录下创建它。

dedecms 在模板里引入php文件夹
(图片来源网络,侵删)

文件路径:/include/extend.func.php

在这个文件中,添加你的自定义函数,这个函数的作用是“引入”并“处理”你在步骤一中创建的 PHP 文件。

<?php
// /include/extend.func.php
/**
 * 自定义标签:引入php文件夹中的文件并返回数据
 * @param string $att 标签属性,'uid="10"'
 * @param string $cfg 标签配置(通常不用)
 * @return string 返回处理后的HTML内容
 */
function GetUserInfoTag($att, $cfg) {
    // 1. 解析标签属性
    // 在模板中写 {dede:getuserinfo uid='10'/}
    // $att 'uid="10"'
    $attArr = [];
    if (preg_match_all('/(\w+)\=[\'\"](.+?)[\'\"]/is', $att, $matches)) {
        foreach ($matches[1] as $key => $val) {
            $attArr[$val] = $matches[2][$key];
        }
    }
    $uid = isset($attArr['uid']) ? intval($attArr['uid']) : 1;
    // 2. 引入你的PHP业务逻辑文件
    // DedeCMS 的全局变量 $cfg_dir 是配置文件目录,通常指向 /include/
    global $cfg_dir;
    $phpFile = $cfg_dir . 'get_user_info.php';
    // 使用 require_once 确保文件只被引入一次
    if (file_exists($phpFile)) {
        // 将 uid 变量传递给 PHP 文件
        $uidForPhp = $uid;
        require_once($phpFile);
        // 3. 处理返回的数据并生成HTML
        // 注意:$data 变量来自 get_user_info.php 文件的 return
        $html = '';
        if (isset($data) && is_array($data)) {
            $html = '<div class="user-info">';
            $html .= '<p>用户ID: ' . $data['uid'] . '</p>';
            $html .= '<p>用户名: ' . $data['name'] . '</p>';
            $html .= '<p>注册时间: ' . $data['regdate'] . '</p>';
            $html .= '</div>';
        }
        return $html;
    } else {
        // 如果文件不存在,返回一个提示
        return '<p style="color:red;">错误:找不到指定的PHP文件。</p>';
    }
}
?>

在模板中使用你的自定义标签

你可以在任何 DedeCMS 模板(.htm 文件)中使用你刚刚创建的 {dede:getuserinfo} 标签了。

{dede:include filename="head.htm"/}
<main>
    <h1>用户信息展示</h1>
    <!-- 使用自定义标签,并传递 uid 属性 -->
    {dede:getuserinfo uid='10'/}
</main>
{dede:include filename="footer.htm"/}

当 DedeCMS 渲染这个模板时,它会调用 extend.func.php 中的 GetUserInfoTag 函数,该函数会引入 get_user_info.php,获取数据,并生成最终的 HTML 代码插入到模板中。


其他方法(不推荐,但需了解)

使用 require/include 在 PHP 文件中引入,然后模板调用

这种方法不如自定义标签灵活,但比直接在模板里写 PHP 要好。

  1. 创建一个 PHP 文件作为“桥梁”: 在 /include/ 下创建 user_info_bridge.php

    // /include/user_info_bridge.php
    require_once 'get_user_info.php'; // 引入你的逻辑文件
    $data = getUserInfo(10); // 调用函数获取数据
    // 将数据赋值给一个模板可以使用的变量
    // 这个变量名需要和你在模板中调用标签时指定的变量名一致
    $fields = $data;
  2. 在模板中使用 {dede:php}: 这个标签允许你在模板中执行一段 PHP 代码。

    {dede:php}
        // 引入桥梁文件
        require_once('/include/user_info_bridge.php');
        // 现在可以在 $fields 中获取到数据了
        // 你可以在这里输出,或者为其他标签赋值
        // 为 {dede:field.name/} 赋值
        $GLOBALS[' fields']['name'] = $fields['name'];
    {/dede:php}
    <p>用户名是:{dede:field.name/}</p>

缺点

  • {dede:php} 标签功能强大,但滥用会破坏模板的整洁性。
  • 不如自定义标签那样封装得干净利落。

总结对比

方法 优点 缺点 推荐度
自定义函数标签 安全、规范、灵活、可复用、符合 MVC 架构 需要修改 extend.func.php 文件,步骤稍多 ⭐⭐⭐⭐⭐ (强烈推荐)
PHP 桥梁文件 + {dede:php} 可以处理较复杂的逻辑 破坏模板整洁性,不够灵活,{dede:php} 滥用有风险 ⭐⭐
直接在模板中使用 PHP 简单直接(表面看) 极其危险、易出错、破坏架构、难以维护 ⭐⭐⭐⭐⭐ (绝对禁止)

为了你的网站安全和长期维护,请务必使用第一种方法:自定义函数标签,这是 DedeCMS 开发的最佳实践。