下面我将从基础到进阶,详细讲解几种常见的传值方法,并提供清晰的示例。

dedecms 写php传值给模板
(图片来源网络,侵删)

核心概念

  • 程序文件: 通常是 .php 文件,index.phparticle_article.php自定义的标签文件.php 等,这是你编写 PHP 逻辑、获取数据并准备传给模板的地方。
  • 模板文件: 通常是 .htm 文件,存放在 /templets/ 目录下,这是你进行页面布局和设计的地方,使用 DedeCMS 的模板引擎标签来显示数据。
  • $dsql 对象: DedeCMS 的数据库操作对象,用于从数据库中查询数据。
  • $tpl 对象: 模板对象,用于加载模板并执行渲染。
  • $GLOBALS 数组: 全局变量数组,一种可以在整个请求生命周期内跨函数、跨文件共享数据的方式。

基础传值(适用于单个页面)

这是最直接、最常用的方法,主要用于对当前页面进行数据填充,如文章标题、内容、作者等。

在 PHP 文件中定义变量并赋值

在你的 PHP 程序文件中,直接定义一个变量,然后将其赋值给一个全局变量 $GLOBALS

示例文件: article_article.php (文章内容页)

<?php
require_once(dirname(__FILE__)."/../include/common.inc.php");
// 获取文章ID,通常从URL中获取,?aid=123
$aid = isset($aid) && is_numeric($aid) ? $aid : 0;
// 使用 dsql 查询数据库,获取文章信息
$sql = "SELECT * FROM `#@__archives` WHERE id = $aid";
$row = $dsql->GetOne($sql);
// 如果文章存在
if (is_array($row)) {
    // --- 传值给模板的核心步骤 ---
    // 1. 将查询到的数据赋值给 $GLOBALS 数组
    // 这样模板中就可以通过 {dede:field} 标签访问这些字段
    $GLOBALS['fields'] = $row;
    // 你也可以自定义一些变量传给模板
    $GLOBALS['my_custom_title'] = '欢迎来到我的网站 - ' . $row['title'];
    $GLOBALS['current_year'] = date('Y');
    // 2. 加载并解析模板
    // 获取文章内容页的模板路径
    $tplfile = DEDETEMPLATE.'/default/article_article.htm';
    // 加载模板文件
    $dtp = new DedeTemplate();
    $dtp->LoadTemplate($tplfile);
    // 将全局变量绑定到模板
    $dtp->Display();
} else {
    showMsg('您查看的文章不存在!', '-1');
    exit();
}
?>

在模板文件中使用变量

在你的 .htm 模板文件中,使用 {dede:field} 标签来显示 PHP 文件中传递过来的 $GLOBALS['fields'] 数组里的值。

dedecms 写php传值给模板
(图片来源网络,侵删)

示例模板: /templets/default/article_article.htm

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">{dede:field.title/} - {dede:global.cfg_webname/}</title>
</head>
<body>
    <h1>{dede:field.title/}</h1> <!-- 显示文章标题 -->
    <p>发布时间:{dede:field.pubdate function="MyDate('Y-m-d H:i',@me)"/}</p> <!-- 显示发布时间,并用函数格式化 -->
    <p>作者:{dede:field.writer/}</p>
    <p>来源:{dede:field.source/}</p>
    <hr>
    <div class="content">
        {dede:field.body/} <!-- 显示文章正文内容 -->
    </div>
    <hr>
    <h2>自定义变量示例</h2>
    <p>这个标题是自定义的:{dede:global.my_custom_title/}</p>
    <p>当前年份是:{dede:global.current_year/}</p>
</body>
</html>

{dede:field} 标签说明:

  • field.name: 访问 $GLOBALS['fields']['name'] 的值。name 必须是数据库表中的字段名。
  • function="...": 对变量值进行二次处理,最常用的就是日期格式化 MyDate()
  • 标签闭合方式。

循环列表传值(适用于列表页)

当你需要传递一个数据集(如文章列表、产品列表)时,你需要使用循环。

在 PHP 文件中准备数据并循环赋值

在 PHP 文件中查询出多条数据,然后在一个 foreach 循环中,将每一行数据都赋值给 $GLOBALS['item']

dedecms 写php传值给模板
(图片来源网络,侵删)

示例文件: list.php (一个自定义的列表页)

<?php
require_once(dirname(__FILE__)."/../include/common.inc.php");
// 查询最新的5篇文章
$sql = "SELECT id, title, pubdate FROM `#@__archives` ORDER BY pubdate DESC LIMIT 5";
$dsql->SetQuery($sql);
$dsql->Execute();
// --- 传值给模板的核心步骤 ---
$article_list = array();
while ($row = $dsql->GetArray()) {
    // 在循环中,将每一行数据赋值给 $GLOBALS['item']
    // 模板中的 {dede:loop} 会遍历这个 $GLOBALS['item']
    $GLOBALS['item'] = $row;
    // 你也可以在这里为每个列表项添加自定义数据
    $GLOBALS['item']['short_title'] = cn_substr($row['title'], 20); // 截取标题前20个字符
    // 将处理好的项添加到列表数组中
    $article_list[] = $GLOBALS['item'];
}
// 将整个列表数组也作为一个全局变量传过去
$GLOBALS['article_list_all'] = $article_list;
// 加载模板
$tplfile = DEDETEMPLATE.'/default/my_list.htm';
$dtp = new DedeTemplate();
$dtp->LoadTemplate($tplfile);
$dtp->Display();
?>

在模板文件中使用循环标签

在模板文件中,使用 {dede:loop} 标签来遍历 PHP 传递过来的 $GLOBALS['item']

示例模板: /templets/default/my_list.htm

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">文章列表 - {dede:global.cfg_webname/}</title>
</head>
<body>
    <h1>最新文章列表</h1>
    <ul>
        {dede:loop}
        <li>
            <!-- 访问 item 中的字段 -->
            <a href="view.php?aid={dede:field.id/}">{dede:field.short_title/}...</a>
            <span>(发布于: {dede:field.pubdate function="MyDate('Y-m-d',@me)"/})</span>
        </li>
        {/dede:loop}
    </ul>
    <hr>
    <h2>另一种方式:直接使用全局列表变量</h2>
    <ul>
        {dede:global name='article_list_all'/}
        {dede:loop}
        <li>
            <a href="view.php?aid={dede:field.id/}">{dede:field.title/}</a>
        </li>
        {/dede:loop}
        {/dede:global}
    </ul>
</body>
</html>

{dede:loop} 标签说明:

  • 它会自动遍历 $GLOBALS['item'] 数组。
  • 循环内部,使用 {dede:field.xxx/} 来访问当前循环项(即 $GLOBALS['item']['xxx'])的值。

使用 assign() 方法(面向对象方式)

DedeCMS 的模板对象 $dtp 也提供了 assign() 方法,这是一种更现代、更清晰的传值方式,尤其适合传递复杂的数据结构。

在 PHP 文件中使用 assign()

示例文件: index.php (首页)

<?php
require_once(dirname(__FILE__)."/include/common.inc.php");
// 获取一些配置信息
$web_name = $cfg_webname;
$web_slogan = $cfg_webname_slogan;
// 获取最新文章
$sql = "SELECT id, title FROM `#@__archives` ORDER BY id DESC LIMIT 10";
$new_articles = $dsql->GetAll($sql);
// --- 使用 assign() 传值 ---
$tpl = new DedeTemplate();
$tpl->LoadTemplate(DEDETEMPLATE.'/default/index.htm');
// assign('模板中使用的变量名', PHP变量)
$tpl->assign('web_name', $web_name);
$tpl->assign('slogan', $web_slogan);
$tpl->assign('latest_articles', $new_articles); // 传递一个数组
// 执行渲染并输出
$tpl->Display();
?>

在模板文件中使用

在模板中,使用 {dede:var.name}{dede:global.name} 来访问 assign() 过来的变量。

示例模板: /templets/default/index.htm

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">{dede:var.web_name/}</title>
</head>
<body>
    <h1>{dede:var.webname/} - {dede:global.cfg_slogan/}</h1> // 混合使用$GLOBALS和assign
    <p>网站标语: {dede:var.slogan/}</p>
    <hr>
    <h2>最新文章</h2>
    <ul>
        {dede:loop name='latest_articles'/}
        <li>
            <a href="view.php?aid={dede:field.id/}">{dede:field.title/}</a>
        </li>
        {/dede:loop}
    </ul>
</body>
</html>

assign() 方法优势:

  • 代码清晰: assign() 的赋值关系非常明确,不易与全局变量混淆。
  • 作用域可控: 变量被明确地绑定到模板对象上,而不是污染全局 $GLOBALS 命名空间。
  • 传递复杂数据: 传递数组、对象等复杂数据结构非常方便。

总结与最佳实践

方法 适用场景 优点 缺点
$GLOBALS 传值 单个页面数据填充(如文章页、单页)。
简单的列表循环。
简单直接,是 DedeCMS 最传统的方式。 容易污染全局命名空间,变量名冲突风险高。
assign() 传值 任何场景,尤其是复杂页面。
需要传递数组、对象等复杂数据时。
大型项目,追求代码清晰度。
代码结构清晰,变量作用域可控,可读性强。 相比 $GLOBALS 多了一步调用,但差别微乎其微。

最佳实践建议:

  1. 优先使用 assign() 方法:对于新开发的功能或重构旧代码,强烈推荐使用 $tpl->assign() 的方式,它更符合现代 PHP 的编程习惯,能让你的代码更易于维护。
  2. 理解 $GLOBALS 传值:由于 DedeCMS 核心文件和许多旧模块都使用 $GLOBALS,你必须理解它的工作原理,以便在修改或扩展现有功能时能够游刃有余。
  3. 保持命名规范:无论使用哪种方法,都请为你的变量起一个有意义且不易冲突的名字($GLOBALS['my_custom_data'] 而不是 $GLOBALS['a'])。
  4. 善用模板函数:在模板中直接进行简单的数据处理(如日期格式化 MyDate()、字符串截取 cn_substr())可以减少 PHP 代码的复杂度,让模板更专注于展示。

通过以上三种方法,你就可以灵活地在 DedeCMS 中实现 PHP 与模板之间的数据交互了。