下面我将从原因、解决方案、安全注意事项三个方面,为你详细拆解并解决这个问题。

根本原因:为什么织梦模板默认不执行PHP?
织梦CMS的核心模板引擎是 dedetemplate.class.php,它主要处理模板标签(如 {dede:arclist})和简单的逻辑,出于对网站安全的考虑,织梦默认不允许在模板文件(.htm)中直接执行PHP代码,如果允许,任何能编辑模板的人(包括黑客)都可以在网站里植入任意恶意PHP代码,这将是巨大的安全漏洞。
织梦官方通过配置,限制了PHP的执行。
解决方案:如何让织梦模板执行PHP?
主要有三种方法,从最推荐到最不推荐排序:
使用 {dede:php} 标签(官方推荐,最安全)
这是织梦官方提供的、在模板中执行PHP代码的标准方法,它有一个明显的优势:代码会被过滤和转义,能有效防止SQL注入和XSS攻击。

使用场景:在模板中需要执行一些简单的PHP逻辑或调用函数。
语法格式:
{dede:php}
// 在这里写你的PHP代码
//
echo "Hello, World!";
$a = 1 + 1;
echo $a;
{/dede:php}
重要提示:
- 不能用于输出循环内容:
{dede:php}标签主要用于执行一次性的代码逻辑,它不适合用来循环输出文章列表、商品列表等,循环输出应该使用织梦自身的循环标签,如{dede:arclist}、{dede:channelartlist}等。 - 代码限制:不能使用
echo、print、die、exit、global、require、include、require_once、include_once等可能带来安全风险的函数或语言结构。 - 变量作用域:在
{dede:php}标签内部,默认无法直接访问模板外的PHP变量,如果需要传递变量,可以通过织梦的全局变量或函数来实现。
示例:获取当前时间并显示

{dede:php}
$time = time();
$formatTime = date('Y-m-d H:i:s', $time);
// 将处理后的变量传递给模板
$GLOBALS['now_time'] = $formatTime;
{/dede:php}
当前时间是:{dede:php}echo $GLOBALS['now_time'];{/dede:php}
(这个例子有点绕,只是为了说明变量传递,更推荐在后台直接使用 [field:pubdate function='strftime("%Y-%m-%d %H:%M:%S",@me)'/] 这样的方式来格式化时间。)
修改 php 标签配置(灵活但有风险)
如果你觉得 {dede:php} 标签限制太多,可以修改织梦的核心配置文件,来启用一个更强大的 php 标签,它允许你写任何PHP代码。
操作步骤:
-
找到核心文件:登录你的网站FTP或文件管理器,找到并打开
/include/dedetemplate.class.php文件。 -
定位代码:搜索
function _ctag函数,找到处理php标签的代码段,通常在if($tagname == 'php')这一部分。 -
修改代码:找到类似
$this->CTags[$this->TagID] = new DedeTagHandler();的代码,在其下面添加一行,将$this->CTags[$this->TagID]->IsReplace = false;改为true。修改前代码示例 (大约在第2200行左右,具体行数可能因版本而异):
// else if($tagname=='list') // 这是系统列表标签 // { // $this->dtp->Assign($tagid, $this->GetList()); // } else if($tagname == 'php') { $this->CTags[$this->TagID] = new DedeTagHandler(); // $this->CTags[$this->TagID]->IsReplace = false; // 这一行是关键 }修改后代码示例:
else if($tagname == 'php') { $this->CTags[$this->TagID] = new DedeTagHandler(); $this->CTags[$this->TagID]->IsReplace = true; // 修改为 true } -
保存文件:保存并上传覆盖
/include/dedetemplate.class.php文件。
使用方法:
修改后,你就可以在模板中使用一个更自由的 php 标签了。
{dede:php}
// 这里可以写任何PHP代码,包括 echo, for, while 等
$arr = array('苹果', '香蕉', '橙子');
foreach ($arr as $value) {
echo $value . '<br />';
}
// 甚至可以包含其他文件
// include_once 'some_other_file.php';
{/dede:php}
⚠️ 安全警告: 此方法会严重降低网站安全性! 修改后,任何能编辑模板的人都可以执行任意PHP代码,这为黑客打开了方便之门。强烈不建议在公共网站或对安全性有要求的网站上使用此方法,仅推荐在本地开发或你完全可控的环境下使用。
修改 php.ini 配置(不推荐,且通常无效)
有些人可能会想到修改 php.ini 中的 short_open_tag 配置,将 Off 改为 On,以支持 <? ?> 这种简写的PHP标签。
为什么此方法不推荐?
- 不解决问题:织梦的模板引擎(
dedetemplate.class.php)在解析模板时,会主动忽略或过滤掉<?php ... ?>这样的代码块,即使你的php.ini允许了,织梦的解析器也不会去执行它,所以这个方法几乎100%无效。 - 服务器级风险:修改
php.ini会影响整个服务器上的所有网站,如果设置不当,可能会导致其他网站出现问题。 - 已过时:简写PHP标签
<? ?>是PHP 4时代的产物,现代PHP(PHP 7+)默认不推荐使用,因为它会和XML声明<?xml ... ?>冲突。
请放弃这个思路,它不是正确的解决方案。
最佳实践与安全建议
-
首选官方方案:优先使用
{dede:php},虽然它有局限,但它是织梦官方设计的,安全性最高,如果它无法满足你的需求,说明你可能需要重新考虑你的网站架构。 -
功能优先用织梦标签:织梦内置了非常丰富的标签,可以实现绝大多数常见的网站功能。
- 时间格式化:
[field:pubdate function="strftime('%Y-%m-%d',@me)"/] - 截取字符串:
[field:description function="cn_substr(@me,100)"/] - 调用栏目:
{dede:channel type='top' row='8'}...{/dede:channel} - 调用文章:
{dede:arclist titlelen='30' row='10'}...{/dede:arclist}在尝试用PHP实现前,先去查阅织梦标签手册,看看是否有现成的标签可以解决问题。
- 时间格式化:
-
复杂逻辑自定义函数:如果某个功能非常复杂,无法用织梦标签实现,最佳实践是不要在模板里写PHP,而是:
- 创建一个自定义函数:在
/include/extend.func.php文件中(如果没有就自己创建一个)添加你的PHP函数。 - 在模板中调用:在模板中使用
{dede:field name='自定义函数名'}或[field:字段名 function='自定义函数名']的方式来调用。
示例:
- 在
/include/extend.func.php中添加函数:if (!function_exists('getCustomSummary')) { function getCustomSummary($string, $len) { // 你的复杂处理逻辑 return mb_substr(strip_tags($string), 0, $len); } } - 在模板中调用:
[field:content function='getCustomSummary(@me, 200)'/]
这种方式既实现了复杂逻辑,又保持了模板的整洁和安全性。
- 创建一个自定义函数:在
| 方法 | 优点 | 缺点 | 推荐度 |
|---|---|---|---|
{dede:php} |
官方支持,安全,有代码过滤 | 功能受限,不能输出循环内容 | ★★★★★ (首选) |
修改 dedetemplate.class.php |
功能强大,灵活,可写任意PHP | 严重安全风险,可能导致被黑客入侵 | ★☆☆☆☆ (仅在本地开发时使用) |
修改 php.ini |
无 | 通常无效,且影响全局服务器配置 | ☆☆☆☆☆ (错误思路) |
遇到织梦模板不执行PHP的问题,请首先检查你是否使用了 {dede:php} 标签,并确认你的代码是否符合其规范,如果确实需要更强大的功能,请优先考虑自定义函数,而不是直接修改核心文件。
