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

核心概念
- 程序文件: 通常是
.php文件,index.php、article_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'] 数组里的值。

示例模板: /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']。

示例文件: 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 多了一步调用,但差别微乎其微。 |
最佳实践建议:
- 优先使用
assign()方法:对于新开发的功能或重构旧代码,强烈推荐使用$tpl->assign()的方式,它更符合现代 PHP 的编程习惯,能让你的代码更易于维护。 - 理解
$GLOBALS传值:由于 DedeCMS 核心文件和许多旧模块都使用$GLOBALS,你必须理解它的工作原理,以便在修改或扩展现有功能时能够游刃有余。 - 保持命名规范:无论使用哪种方法,都请为你的变量起一个有意义且不易冲突的名字(
$GLOBALS['my_custom_data']而不是$GLOBALS['a'])。 - 善用模板函数:在模板中直接进行简单的数据处理(如日期格式化
MyDate()、字符串截取cn_substr())可以减少 PHP 代码的复杂度,让模板更专注于展示。
通过以上三种方法,你就可以灵活地在 DedeCMS 中实现 PHP 与模板之间的数据交互了。
