在 DedeCMS 中,PHP 嵌套是一个非常核心且强大的功能,它允许你在模板文件(.htm)中直接编写 PHP 代码,从而实现更灵活、更复杂的页面逻辑,而不仅仅局限于 DedeCMS 自带的标签。
这主要分为两种情况:
- 在模板中直接嵌入 PHP 代码:适用于执行一些简单的逻辑或调用 PHP 函数。
- 在自定义标签中嵌套 PHP 代码:这是更高级、更推荐的方式,用于封装复杂的业务逻辑,使模板更整洁。
在模板中直接嵌入 PHP 代码
DedeCMS 模板引擎默认支持 {dede:php}...{/dede:php} 标签对,用于在模板中执行 PHP 代码。
基本语法
{dede:php}
// 在这里写你的 PHP 代码
echo "Hello, World from PHP!";
{/dede:php}
访问 DedeCMS 全局变量和函数
在 {dede:php} 标签内,你可以像在普通 PHP 文件中一样,访问 DedeCMS 的全局变量和函数,获取当前栏目ID、网站名称等。
示例:获取并显示当前栏目的名称
{dede:php}
// global $dsql; 是必须的,用于访问全局数据库连接对象
global $dsql;
// 获取当前栏目ID
$typeid = $GLOBALS['typeid'];
// typeid 存在,则查询栏目名称
if ($typeid > 0) {
$query = "SELECT typename FROM `#@__arctype` WHERE id = $typeid";
$row = $dsql->GetOne($query);
if ($row) {
echo "当前栏目是:" . $row['typename'];
}
} else {
echo "您正在访问首页。";
}
{/dede:php}
代码解析:
global $dsql;:声明 DedeCMS 的数据库操作对象为全局变量,这是进行数据库查询的前提。$GLOBALS['typeid']:这是一个核心的全局变量,用于获取当前页面的栏目ID,在列表页、文章页等页面都有效。$dsql->GetOne($query):执行一条 SQL 查询并返回第一条结果(关联数组形式)。#@__:这是 DedeCMS 的表前缀替换符,如果你的数据库表前缀是dede_,#@__arctype就会被替换成dede_arctype。
在循环中使用 PHP
如果你想在 {dede:php} 中使用 DedeCMS 的循环标签(如 {dede:arclist})获取的数据,你需要先将数据传递给 PHP。
示例:获取文章列表,并用 PHP 循环处理
{dede:arclist row='5' titlelen='30'}
{dede:php}
// 注意:这里的 $GLOBALS['item'] 是 arclist 标签在循环中当前项的数据
$item = $GLOBALS['item'];
echo "<div style='border:1px solid #ccc; padding:10px; margin:5px;'>";
echo "<h3>" . $item['title'] . "</h3>";
echo "<p>发布时间:" . date('Y-m-d H:i:s', $item['pubdate']) . "</p>";
echo "<p>内容简介:" . $item['description'] . "</p>";
echo "</div>";
{/dede:php}
{/dede:arclist}
代码解析:
{dede:arclist}先正常执行,它会循环生成内容。- 在每一次循环中,当前文章的数据会被存入全局变量
$GLOBALS['item']中。 {dede:php}代码块会为arclist的每一项执行一次,此时你可以从$GLOBALS['item']中取出当前项的数据进行处理。
在自定义标签中嵌套 PHP 代码(推荐)
直接在模板中写大量 PHP 代码会使模板变得混乱,难以维护,更专业、更推荐的做法是自定义一个 PHP 函数,然后在模板中通过 DedeCMS 的自定义标签 {dede:mytag} 来调用它。
步骤 1:创建自定义函数文件
在 /include/helpers/ 目录下创建一个新的 PHP 文件,extend.helper.php,这个文件专门用来存放你的自定义函数。
在 extend.helper.php 中编写你的 PHP 函数:
<?php
if(!defined('DEDEINC')) exit('Request Error!');
/**
* 获取指定栏目的文章总数
* @param int $typeid 栏目ID
* @return int 文章总数
*/
function GetArticleCount($typeid = 0)
{
// 如果没有传入栏目ID,则尝试获取当前栏目ID
if ($typeid == 0) {
$typeid = isset($GLOBALS['typeid']) ? $GLOBALS['typeid'] : 0;
}
if ($typeid <= 0) {
return 0;
}
global $dsql;
$query = "SELECT COUNT(*) AS total FROM `#@__archives` WHERE typeid = $typeid";
$row = $dsql->GetOne($query);
// 返回查询结果
return $row['total'];
}
?>
代码解析:
if(!defined('DEDEINC')) exit('Request Error!');:这是 DedeCMS 文件的标准开头,用于防止直接访问。- 函数名
GetArticleCount可以自定义,建议有明确的前缀(如My,Custom)以避免与系统函数冲突。 - 函数内部使用了标准的 DedeCMS 数据库查询方法,逻辑清晰,可复用。
步骤 2:在模板中调用自定义函数
你可以在任何模板文件中使用 {dede:mytag} 标签来调用你刚刚创建的函数了。
示例:在栏目页显示当前栏目的文章总数
<h2>{dede:field.typename/}</h2>
<p>本栏目共有 <strong>{dede:mytag name='GetArticleCount'/}</strong> 篇文章。</p>
高级用法:向函数传递参数
如果你的函数需要参数,可以在 name 属性中使用 来传递。
假设我们修改 extend.helper.php 中的函数:
function GetArticleCount($typeid = 0)
{
// ... 函数体不变 ...
}
在模板中调用:
<!-- 显示栏目ID为 5 的文章总数 -->
<p>栏目ID为5的文章总数为:{dede:mytag name='GetArticleCount typeid=5'/}</p>
<!-- 显示当前栏目的文章总数(typeid参数可选) -->
<p>当前栏目的文章总数为:{dede:mytag name='GetArticleCount'/}</p>
总结与注意事项
| 特性 | {dede:php} 嵌套 |
自定义标签 {dede:mytag} |
|---|---|---|
| 位置 | 直接写在模板 .htm 文件中 |
写在 /include/helpers/ 的 .php 文件中 |
| 复杂度 | 适合简单、临时的逻辑 | 适合复杂、可复用的业务逻辑 |
| 可维护性 | 差,模板和逻辑混杂 | 高,逻辑与表现分离 |
| 复用性 | 差,只能在当前模板使用 | 高,可在全站所有模板调用 |
| 安全性 | 较低,需小心处理用户输入,防止SQL注入等 | 较高,PHP代码可以更好地进行封装和安全检查 |
最佳实践建议:
- 优先使用自定义标签:对于任何需要重复使用或逻辑较为复杂的代码,都应封装成自定义函数,这是保持模板干净、专业的关键。
- 谨慎使用
{dede:php}:仅用于一些非常简单的、一次性的逻辑输出,避免在模板中编写复杂的数据库操作或循环。 - 注意安全性:当处理来自用户输入(如表单、URL参数)的数据时,务必进行过滤和转义,防止SQL注入和XSS攻击,DedeCMS 提供了
HtmlReplace()等函数可以帮助处理。 - 性能考虑:PHP 代码是在服务器端执行的,复杂的逻辑会增加服务器负担,尽量将复杂的计算和查询放在自定义标签中,并做好缓存。
- 开启模板缓存:确保 DedeCMS 的模板缓存是开启的(后台系统设置 -> 性能选项),这样可以提高页面加载速度,自定义标签的函数结果也会被缓存。
