织梦CMS为了安全考虑,不推荐直接在模板文件中使用 $_GET,直接使用存在XSS(跨站脚本)等安全风险。

(图片来源网络,侵删)
正确且官方推荐的方法是:通过织梦提供的内置函数 GetRequest() 或 dede_getrequest() 来获取和净化 $_GET 参数。
下面我将详细介绍几种常用场景和具体方法。
核心方法:使用 GetRequest() 函数
GetRequest() 函数的作用是安全地从 $_GET 或 $_POST 数组中获取变量,并对其进行净化处理,防止恶意代码注入。
语法:

(图片来源网络,侵删)
GetRequest($key, $type = 'html', $default = '')
参数说明:
$key(string): 你要获取的$_GET参数的键名,也就是 URL 中 后面的变量名。$type(string): 对获取到的值进行净化的类型,这是非常重要的安全步骤。'html': 默认值,将 HTML 标签转换为实体,防止XSS攻击。(最常用,用于显示)'text': 去除所有 HTML 标签,只保留纯文本。'float': 转换为浮点数。'int': 转换为整数。'string': 仅去除一些危险的字符,但保留大部分字符。
$default(string): 如果指定的$_GET参数不存在,则返回这个默认值。
获取并显示一个简单的筛选参数
假设你的URL是这样的:/plus/list.php?tid=1&keywords=织梦CMS
你希望在列表页获取 keywords 这个参数,并把它显示在页面上。
操作步骤:

(图片来源网络,侵删)
- 打开你的列表页模板文件,通常位于
/templets/default/list_栏目ID.htm。 - 在你需要显示关键词的地方,使用
GetRequest()函数。
示例代码:
<div class="search-keywords">
当前搜索的关键词是:<strong>{dede:global.name/}</strong>
{dede:geturl runphp='yes'}
if(@me != ''){
@me = ' - 搜索关键词:'.@me;
}else{
@me = '';
}
{/dede:geturl}
</div>
<!-- 使用 GetRequest 安全获取 keywords 参数 -->
<div class="filter-info">
{dede:global.cfg_webname/} > {dede:field.title/}
{if GetRequest('keywords','html') != ''}
<span>筛选条件:<i>{dede:global.keywords/}</i></span>
{/if}
</div>
<!-- 更推荐的做法,直接获取并显示 -->
<p>您正在搜索:<strong class="highlight">[field:keywords function="GetRequest('keywords', 'html')"/]</strong></p>
代码解析:
GetRequest('keywords', 'html'):'keywords': 获取URL中keywords=的值。'html': 对获取到的值进行HTML实体化转义,确保即使用户输入了<script>alert('xss')</script>这样的恶意代码,也会被当作普通文本显示,而不会被执行。
if GetRequest('keywords','html') != '': 判断该参数是否存在,如果存在则显示一个提示框。
获取参数用于SQL查询(高级筛选)
这是最核心的用法,比如根据URL中的 price(价格区间)来筛选文章。
假设URL是:/plus/list.php?tid=5&price=1-100
你需要在 list_5.htm 模板中,根据 price 参数来修改 select 查询语句。
操作步骤:
- 打开列表页模板文件
/templets/default/list_5.htm。 - 找到
{dede:list}- 使用
runphp='yes'在{dede:geturl}或其他标签内修改SQL。 - 使用
示例代码:
{dede:list pagesize='10' titlelen='50'}
<!-- 这里是文章列表的常规循环内容 -->
<li>
<a href="[field:arcurl/]">[field:title/]</a>
<span>价格:[field:price/]</span>
</li>
{/dede:list}
<div class="page">{dede:pagelist listsize='4' listitem='info,index,end,pre,next,pageno'}</div>
修改后的 list_5.htm (关键部分):
{dede:sql sql='SELECT * FROM `#@__archives` WHERE typeid = 5'}
{dede:list}
...
{/dede:list}
{/dede:sql}
<!-- 或者更推荐的方式,在原有list标签基础上添加条件 -->
{dede:list pagesize='10' titlelen='50'}
...
{/dede:list}
<!-- 我们可以在模板顶部定义一个变量,然后在标签中使用 -->
{dede:geturl runphp='yes'}
$price = GetRequest('price', 'text');
if($price){
// 简单的参数校验,这里假设格式是 "最小值-最大值"
$price_arr = explode('-', $price);
if(count($price_arr) == 2 && is_numeric($price_arr[0]) && is_numeric($price_arr[1])){
// 将SQL条件存入全局变量,供标签使用
global $dsql;
$addquery = " AND arc.price BETWEEN {$price_arr[0]} AND {$price_arr[1]}";
$GLOBALS['addfields'] = "price"; // 确保price字段在附加表里
}
}
@me = '';
{/dede:geturl}
<!-- 在list标签中使用附加查询 -->
{dede:list pagesize='10' titlelen='50' addfields='price'}
...
{/dede:list}
更简单、更标准的做法(推荐):
织梦的 {dede:list} 和 {dede:arclist} 标签本身就支持通过 refObj 获取当前页面的环境变量,我们可以利用这一点。
- 在模板文件的开头
<head>标签后添加一段PHP代码:
<head>
<meta charset="UTF-8">{dede:field.title/}_{dede:global.cfg_webname/}</title>
</head>
<body>
<!-- 在这里添加PHP代码块 -->
<?php
// 获取当前页面的环境对象
$refObj = &$this;
// 使用 GetRequest 安全获取 price 参数,并校验
$price_filter = GetRequest('price', 'text');
$addSql = '';
if ($price_filter) {
$price_range = explode('-', $price_filter);
if (count($price_range) == 2 && is_numeric($price_range[0]) && is_numeric($price_range[1])) {
// 假设价格字段存储在附加表 `dede_archives_ex` 中,字段名为 `price`
// 注意:这需要你在后台模型管理中为该栏目添加了“价格”字段
$addSql = " AND (SELECT price FROM `#@__archives_ex` WHERE aid = arc.id) BETWEEN {$price_range[0]} AND {$price_range[1]}";
}
}
// 将拼接好的SQL条件存入环境对象,供list标签使用
$refObj->addSql = $addSql;
?>
<!-- 接下来是模板的常规内容 -->
<div class="filter">
<a href="{dede:global.cfg_cmsurl/}/plus/list.php?tid={dede:field.id/}">全部</a>
<a href="{dede:global.cfg_cmsurl/}/plus/list.php?tid={dede:field.id/}&price=0-50">0-50元</a>
<a href="{dede:global.cfg_cmsurl/}/plus/list.php?tid={dede:field.id/}&price=50-100">50-100元</a>
</div>
<!-- 在 list 标签中使用这个自定义的SQL条件 -->
{dede:list pagesize='10' titlelen='50'}
<li>
<a href="[field:arcurl/]">[field:title/]</a>
</li>
{/dede:list}
<div class="page">{dede:pagelist listsize='4' listitem='info,index,end,pre,next,pageno'}</div>
</body>
代码解析:
<?php ... ?>: 在模板中嵌入PHP代码。$refObj = &$this;: 获取当前模板解析的环境对象。$addSql = '...': 我们拼接了一个SQLWHERE条件片段。$refObj->addSql = $addSql;: 将这个条件片段赋值给环境对象的addSql属性。{dede:list addSql=''}:addSql是{dede:list}标签支持的一个属性,它会自动将我们设置的$refObj->addSql的值附加到最终的SQL查询语句中。(注意:此方法在部分旧版本或特殊配置下可能不生效,如果无效,请参考场景二中的第一种方法,直接修改SQL标签)。
总结与最佳实践
- 安全第一:永远不要在模板里直接使用
$_GET['xxx'],请务必使用GetRequest('xxx', 'html')或GetRequest('xxx', 'text')。 - 明确用途:
- 如果只是显示给用户看,用
GetRequest('key', 'html')。 - 如果要用作数字(如ID、价格),用
GetRequest('key', 'int')。 - 如果要用作纯文本(如搜索关键词),用
GetRequest('key', 'text')。
- 如果只是显示给用户看,用
- SQL注入防范:当获取的参数用于构造SQL语句时,除了使用
GetRequest进行基础净化外,最好还进行严格的格式校验(如判断是否为数字、是否符合特定格式等),或者使用织梦提供的标签机制(如addSql)来拼接SQL,而不是直接拼接字符串。 - 调试技巧:如果不确定获取到的值是什么,可以在模板里临时输出查看:
<pre> {dede:geturl runphp='yes'} $my_param = GetRequest('keywords', 'html'); print_r($my_param); @me = ''; {/dede:geturl} </pre>
遵循以上方法,你就可以安全、高效地在织梦CMS模板中接收和处理 $_GET 参数了。
