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

织梦cms 模板接收$get参数
(图片来源网络,侵删)

正确且官方推荐的方法是:通过织梦提供的内置函数 GetRequest()dede_getrequest() 来获取和净化 $_GET 参数

下面我将详细介绍几种常用场景和具体方法。


核心方法:使用 GetRequest() 函数

GetRequest() 函数的作用是安全地从 $_GET$_POST 数组中获取变量,并对其进行净化处理,防止恶意代码注入。

语法:

织梦cms 模板接收$get参数
(图片来源网络,侵删)
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 这个参数,并把它显示在页面上。

操作步骤:

织梦cms 模板接收$get参数
(图片来源网络,侵删)
  1. 打开你的列表页模板文件,通常位于 /templets/default/list_栏目ID.htm
  2. 在你需要显示关键词的地方,使用 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 查询语句。

操作步骤:

  1. 打开列表页模板文件 /templets/default/list_5.htm
  2. 找到 {dede:list}
  3. 使用 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 获取当前页面的环境变量,我们可以利用这一点。

  1. 在模板文件的开头 <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 = '...': 我们拼接了一个SQL WHERE 条件片段。
  • $refObj->addSql = $addSql;: 将这个条件片段赋值给环境对象的 addSql 属性。
  • {dede:list addSql=''}: addSql{dede:list} 标签支持的一个属性,它会自动将我们设置的 $refObj->addSql 的值附加到最终的SQL查询语句中。(注意:此方法在部分旧版本或特殊配置下可能不生效,如果无效,请参考场景二中的第一种方法,直接修改SQL标签)。

总结与最佳实践

  1. 安全第一:永远不要在模板里直接使用 $_GET['xxx'],请务必使用 GetRequest('xxx', 'html')GetRequest('xxx', 'text')
  2. 明确用途
    • 如果只是显示给用户看,用 GetRequest('key', 'html')
    • 如果要用作数字(如ID、价格),用 GetRequest('key', 'int')
    • 如果要用作纯文本(如搜索关键词),用 GetRequest('key', 'text')
  3. SQL注入防范:当获取的参数用于构造SQL语句时,除了使用 GetRequest 进行基础净化外,最好还进行严格的格式校验(如判断是否为数字、是否符合特定格式等),或者使用织梦提供的标签机制(如 addSql)来拼接SQL,而不是直接拼接字符串。
  4. 调试技巧:如果不确定获取到的值是什么,可以在模板里临时输出查看:
    <pre>
    {dede:geturl runphp='yes'}
        $my_param = GetRequest('keywords', 'html');
        print_r($my_param);
        @me = '';
    {/dede:geturl}
    </pre>

遵循以上方法,你就可以安全、高效地在织梦CMS模板中接收和处理 $_GET 参数了。