核心方法:使用 dede_filterSearch() 函数
织梦CMS在处理搜索时,已经内置了一个核心的安全过滤函数 dede_filterSearch(),这个函数位于 /include/arc.searchview.class.php 文件中,是所有搜索操作的第一道防线。

(图片来源网络,侵删)
函数定义:
function dede_filterSearch($keyword)
{
$keyword = preg_replace("#\"#", "", $keyword);
$keyword = htmlspecialchars($keyword);
return $keyword;
}
分析这个函数做了什么:
preg_replace("#\"#", "", $keyword);:移除搜索关键词中的双引号 (),双引号在某些数据库查询中可能会被用来闭合引号,是SQL注入的常见手段。htmlspecialchars($keyword);:将特殊字符转换为HTML实体。&->&- ->
" - ->
' <-><>->>- 这一步是防止XSS攻击的关键,确保用户输入的脚本代码不会被浏览器执行。
如何应用: 你不需要手动调用这个函数,织梦的搜索模块在处理关键词时,会自动调用它,但如果你要开发自己的搜索功能或修改搜索逻辑,就应该在获取关键词后立即调用它。
// 假设 $keyword 是从 $_GET['q'] 获取的用户输入 $keyword = isset($_GET['q']) ? trim($_GET['q']) : ''; // 使用织梦内置函数进行过滤 $filtered_keyword = dede_filterSearch($keyword); // 现在可以使用 $filtered_keyword 进行安全的数据库查询或其他操作
高级过滤与自定义规则
dede_filterSearch() 函数虽然基础,但可能无法满足所有场景,你可能需要:

(图片来源网络,侵删)
- 过滤掉一些特定的非法词语。
- 限制关键词的长度。
- 防止SQL注入的更高级形式。
你可以通过以下两种方式实现更高级的过滤。
方法1:修改 dede_filterSearch() 函数(不推荐,但有效)
直接编辑 /include/arc.searchview.class.php 文件,修改 dede_filterSearch() 函数,添加你自己的过滤规则。
示例:添加非法词过滤和长度限制
// 在 /include/arc.searchview.class.php 中找到这个函数并替换
function dede_filterSearch($keyword)
{
// 1. 原始过滤
$keyword = preg_replace("#\"#", "", $keyword);
$keyword = htmlspecialchars($keyword);
// 2. 自定义过滤:定义非法词列表
$banned_words = array('垃圾', '广告词', '违规内容');
foreach ($banned_words as $word) {
$keyword = str_replace($word, '***', $keyword);
}
// 3. 自定义过滤:限制关键词长度
if (mb_strlen($keyword, 'UTF-8') > 20) {
$keyword = mb_substr($keyword, 0, 20, 'UTF-8');
// 可以在这里记录日志,提示用户关键词过长
// showMsg('搜索关键词过长,已自动截取', '-1');
// exit();
}
return $keyword;
}
⚠️ 注意:

(图片来源网络,侵删)
- 直接修改核心文件在织梦升级后会被覆盖,需要重新修改。
- 修改前务必备份原文件。
方法2:在搜索处理文件中添加自定义过滤(推荐)
这是更安全、更灵活的方法,织梦的搜索请求通常由 plus/search.php 处理,你可以在这里添加自己的过滤逻辑,然后再调用织梦的核心搜索功能。
步骤:
- 打开搜索处理文件:
/plus/search.php - 找到关键词获取位置:在文件中找到类似
$q = trim($_GET['q']);的代码。 - 添加自定义过滤逻辑:在获取关键词后,添加你自己的过滤代码。
示例:在 plus/search.php 中添加高级过滤
<?php
require_once(dirname(__FILE__)."/../include/config_base.php");
require_once(DEDEINC.'/arc.search.class.php');
// 1. 获取用户输入的关键词
$q = isset($_GET['q']) ? trim($_GET['q']) : '';
// 2. 【自定义】开始进行高级过滤
if (!empty($q)) {
// a. 非法词过滤
$banned_words = array('垃圾', '广告词', '违规内容');
foreach ($banned_words as $word) {
if (strpos($q, $word) !== false) {
die('搜索内容包含非法词语,已被系统拦截!');
}
}
// b. 长度限制
if (mb_strlen($q, 'UTF-8') > 20) {
$q = mb_substr($q, 0, 20, 'UTF-8');
// 也可以选择跳转到错误页面
// ShowMsg('搜索关键词过长,已自动截取', 'javascript:history.go(-1);');
// exit();
}
// c. 更严格的正则表达式过滤(防止SQL注入和特殊字符)
// 只允许中文字符、英文字母、数字和常见符号
if (!preg_match("/^[\x{4e00}-\x{9fa5}a-zA-Z0-9\s\.\+\-\*\(\)\[\]\{\}\?\!\@\#\$\%\^\&\_\~\|]+$/u", $q)) {
die('搜索内容包含非法字符,请重新输入!');
}
}
// 【自定义】过滤结束
// 3. 调用织梦内置的过滤函数(双重保险)
$q = dede_filterSearch($q);
// ... 后续代码保持不变,将过滤后的 $q 传给搜索类 ...
$typeid = isset($typeid) && is_numeric($typeid) ? $typeid : 0;
$mid = isset($mid) && is_numeric($mid) ? $mid : 0;
$mobile = isset($mobile) ? $mobile : '';
$searchtype = isset($searchtype) ? $searchtype : 'titlekeyword';
$channelid = empty($channelid) ? 0 : intval($channelid);
// 实例化搜索类
$sp = new Search($q, $typeid, $searchtype, $channelid, $mid, $mobile);
$sp->IsError = true;
$sp->PageSize = 10;
// 获得搜索结果的HTML代码
$artlist = $sp->GetResultlist('artlist');
// ... 后续代码 ...
完整实例:创建一个安全的搜索页面
假设你想创建一个自定义的搜索页面,而不是使用默认的 plus/search.php。
-
创建模板文件
templets/default/mysearch.htm<form action="/mysearch.php" method="get"> <input type="text" name="q" placeholder="请输入搜索关键词"> <button type="submit">搜索</button> </form> -
创建处理文件
mysearch.php(放在网站根目录)<?php require_once('include/config_base.php'); // 引入织梦基础配置 require_once(DEDEINC.'/arc.search.class.php'); // 1. 获取并过滤关键词 $keyword = isset($_GET['q']) ? trim($_GET['q']) : ''; // 如果关键词为空,可以跳转到首页或显示提示 if (empty($keyword)) { ShowMsg('请输入搜索关键词', '/'); exit(); } // 2. 【核心安全过滤】使用织梦内置函数 $safe_keyword = dede_filterSearch($keyword); // 3. 【可选】自定义额外过滤 // 过滤掉SQL关键字 $sql_keywords = array('select', 'insert', 'update', 'delete', 'union', 'script', 'iframe'); foreach ($sql_keywords as $sql_word) { if (stripos($safe_keyword, $sql_word) !== false) { die('您的输入可能包含不安全内容,搜索已终止。'); } } // 4. 使用过滤后的关键词进行搜索 $typeid = 0; // 所有栏目 $searchtype = 'titlekeyword'; // �标题和关键词搜索 $channelid = 0; // 所有模型 $mid = 0; // 所有会员 $mobile = ''; // 实例化搜索类 $search = new Search($safe_keyword, $typeid, $searchtype, $channelid, $mid, $mobile); $search->PageSize = 10; // 每页显示10条 $search->IsError = true; // 开启错误提示 // 获取分页和结果列表 $geturl = "mysearch.php?q=".urlencode($safe_keyword); // 搜索页URL $pagelist = $search->GetPageList($geturl); $artlist = $search->GetResultlist('artlist'); // 使用默认的搜索结果列表模板 // 5. 输出结果 $dtp = new DedeTagParse(); $dtp->LoadTemplate($templet); $dtp->Assign('artlist', $artlist); $dtp->Assign('pagecount', $search->GetPageCount()); $dtp->Assign('pagelist', $pagelist); $dtp->Display(); ?>
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
dede_filterSearch() |
官方内置,基础安全,无需修改 | 功能单一,无法满足复杂需求 | 默认搜索,或对安全要求不高的场景。 |
| 修改核心函数 | 能统一处理所有搜索请求 | 升级后会被覆盖,维护成本高 | 有特殊且固定的过滤需求,且不介意修改核心文件。 |
| 在处理文件中自定义 | 灵活、安全、可维护,不影响核心文件 | 需要手动在特定文件中添加代码 | 强烈推荐,无论是修改默认搜索还是开发新搜索功能,都应采用此方法。 |
最佳实践建议:
- 始终使用
dede_filterSearch()作为基础过滤。 - 在搜索请求的入口文件(如
plus/search.php或你自定义的处理文件中)添加自定义的过滤规则,如非法词、长度限制、正则表达式等。 - 对所有来自用户输入的数据(
$_GET,$_POST,$_REQUEST)保持警惕,不要直接用于数据库查询。
通过以上组合,你可以为你的织梦网站构建一个既安全又灵活的搜索系统。
