DedeCMS 本身只提供了简单的关键词搜索功能,要实现多条件搜索,我们需要对系统进行一些修改,核心思路是:修改搜索表单、修改搜索处理逻辑、修改搜索结果页模板。

下面我将分步为您讲解,并提供最常用、最稳妥的修改方法。
第一步:创建多条件搜索表单
这是用户交互的入口,我们需要一个包含多个输入框的下拉菜单或表单。
目标文件: templets/default/search.htm (这是默认的搜索模板,你可以根据你的模板路径进行修改)
**
在 search.htm 文件中,找到默认的搜索表单,并将其修改为包含多个条件的表单。

示例代码:
<form name="formsearch" action="{dede:global.cfg_cmspath/}/search.php" target="_blank">
<div class="formsearch">
<span>关键词:</span>
<input type="text" name="q" class="search-keyword" id="search-keyword" />
<select name="typeid" id="typeid">
<option value="0">所有栏目</option>
{dede:channel type='self' row='10'}
<option value='{typeid}'>{typename}</option>
{/dede:channel}
</select>
<select name="time">
<option value="0">所有时间</option>
<option value="1">lt;/option>
<option value="3">三天内</option>
<option value="7">一周内</option>
<option value="30">一月内</option>
</select>
<button type="submit" class="search-submit">搜索</button>
</div>
</form>
代码解释:
action="{dede:global.cfg_cmspath/}/search.php": 表单提交的目标是search.php文件,这是 DedeCMS 处理搜索的核心文件。name="q": 这是默认的关键词输入框,search.php会识别这个参数。name="typeid": 新增的栏目选择框。typeid是 DedeCMS 内置的用于指定栏目 ID 的参数。name="time": 新增的时间范围选择框,这个参数time是 DedeCMS 自带支持的,用于限定文章的发布时间。{dede:channel type='self' row='10'}: 这是一个 DedeCMS 的标签,用于获取当前栏目及其子栏目的列表,方便用户选择。
第二步:修改搜索处理核心文件 search.php
这是实现多条件搜索逻辑的关键,我们需要修改 search.php,让它能够处理我们新增的 typeid 和 time 参数。
目标文件: /search.php

修改步骤:
- 找到
search.php文件。 - 找到获取搜索关键词的代码,通常是
$q = trim($_GET['q']);。 - 在其下方,添加获取我们新增参数的代码。
修改后的 search.php 关键代码示例:
<?php
require_once (dirname(__FILE__) . "/include/common.inc.php");
// 获取搜索关键词
$q = trim($_GET['q']);
// 获取栏目ID
$typeid = isset($_GET['typeid']) && is_numeric($_GET['typeid']) ? (int)$_GET['typeid'] : 0;
// 获取时间范围
$keywordtime = isset($_GET['time']) ? (int)$_GET['time'] : 0;
// 如果有关键词,则进行搜索
if ($q != '') {
// --- 这是关键部分:构建 SQL 查询条件 ---
$addquery = " arc.arcrank > -1 "; // 排除草稿
// 1. 添加栏目条件
if ($typeid > 0) {
// $typeid = GetSonIds($typeid); // 如果要包含子栏目,取消这行注释,GetSonIds是DedeCMS内置函数
$addquery .= " AND arc.typeid IN ($typeid) ";
}
// 2. 添加时间条件
if ($keywordtime > 0) {
$ntime = time() - $keywordtime * 3600 * 24;
$addquery .= " AND arc.senddate > $ntime ";
}
// --- 调用DedeCMS的搜索函数 ---
$searchsql = "SELECT arc.*,tp.typedir,tp.typename,tp.corank,tp.isdefault,tp.defaultname,tp.namerule,
tp.namerule2,tp.ispart,tp.moresite,tp.siteurl,tp.sitepath
FROM `#@__archives` arc
LEFT JOIN `#@__arctype` tp ON arc.typeid=tp.id
WHERE $addquery AND arc.title LIKE '%$q%' ORDER BY arc.aid DESC";
$keyword = $q;
$typeid = 0; // 搜索页通常不显示特定栏目,所以这里设为0
$channeltype = 0;
$searchtype = 'keyword';
$money = -1;
$mid = 0;
$dopost = '';
// 调用搜索函数
$query = "SELECT arc.*,tp.typedir,tp.typename,tp.corank,tp.isdefault,tp.defaultname,tp.namerule,tp.namerule2,tp.ispart,tp.moresite,tp.siteurl,tp.sitepath
FROM `#@__archives` arc
LEFT JOIN `#@__arctype` tp ON arc.typeid=tp.id
WHERE $addquery AND arc.title LIKE '%$q%' ORDER BY arc.aid DESC";
$sp = new SearchPartView();
$sp->GetKeywordLists($q);
$sp->GetArcLists($query);
} else {
// 如果没有关键词,可以跳转到首页或显示提示
ShowMsg('请输入搜索关键词!', '-', 0, 1);
exit();
}
?>
代码解释:
- 获取参数:我们通过
$_GET获取typeid和time,并进行简单的类型转换和安全性检查。 - 构建
$addquery:这是核心,我们初始化一个$addquery变量来存放额外的 SQL 查询条件。- 栏目条件:如果用户选择了栏目(
$typeid > 0),我们就将typeid IN ($typeid)添加到查询条件中。IN关键字可以同时匹配多个栏目 ID。 - 时间条件:如果用户选择了时间范围(
$keywordtime > 0),我们就计算出时间戳,并将senddate > $ntime添加到查询条件中。
- 栏目条件:如果用户选择了栏目(
- 组合 SQL:最终的查询语句
searchsql在原有的arc.title LIKE '%$q%'基础上,通过AND连接了我们新加的$addquery条件。 - 调用函数:
$sp->GetArcLists($query);这行代码会执行查询,并将结果传递给模板。
注意:上面的代码直接构建了 SQL 查询,更规范的做法是使用 DedeCMS 的
GetSonIds函数来获取指定栏目及其所有子栏目的 ID,这样在搜索某个栏目时,其子栏目的文章也会被包含进来,你可以取消注释$typeid = GetSonIds($typeid);来实现这个功能。
第三步:修改搜索结果页模板 search.php 对应的模板文件
search.php 在执行时会调用一个模板文件来显示结果,默认情况下,它使用 templets/default/search.htm,但我们第一步已经修改了这个文件,所以我们需要为结果页创建一个新的模板,或者让结果页使用一个专门的模板文件。
使用独立的搜索结果模板(推荐)
-
在
templets/default/目录下创建一个新文件,search_list.htm。 -
在
search.php文件中,找到$sp->GetArcLists($query);这行代码,在它之前添加一行代码来指定模板文件:// 在 $sp->GetArcLists($query); 之前添加 $sp->SetTemplet(templets('default/search_list.htm')); -
编辑
search_list.htm:这个文件的结构和列表页(list.htm)非常相似,你可以复制一份list.htm的内容,然后根据需要进行修改。search_list.htm示例代码:{dede:include filename="head.htm"/} <div class="main"> <div class="path"> <a href="{dede:global.cfg_cmsurl/}/">首页</a> > 搜索结果 </div> <div class="search-form"> <!-- 可以放一个返回搜索框的表单 --> <form name="formsearch" action="{dede:global.cfg_cmspath/}/search.php" target="_blank"> <input type="text" name="q" value="{dede:global name='keyword'/}" class="search-keyword" /> <button type="submit">搜索</button> </form> </div> <div class="result"> <p>搜索 "<strong>{dede:global name='keyword'/}</strong>" 找到 <strong>{dede:global name='resultcount'/}</strong> 个结果</p> </div> <div class="listbox"> <!-- 使用 {dede:list} 标签循环输出搜索结果 --> {dede:list pagesize='10'} <h3><a href="[field:arcurl/]">[field:title/]</a></h3> <p class="intro">[field:description function='cn_substr(@me,200)'/]...</p> <div class="info"> <span class="type">栏目:[field:typename/]</span> <span class="time">发布时间:[field:pubdate function="MyDate('Y-m-d',@me)"/]</span> </div> {/dede:list} </div> <!-- 分页 --> <div class="page"> {dede:pagelist listsize='4'/} </div> </div> {dede:include filename="foot.htm"/}模板标签说明:
{dede:global name='keyword'/}: 显示用户搜索的关键词。{dede:global name='resultcount'/}: 显示搜索到的结果总数。{dede:list}: 循环输出搜索到的文章列表,用法和列表页完全一样。
总结与注意事项
- 文件备份:在修改任何核心文件(如
search.php)之前,请务必备份原始文件,以防出错。 - SEO:多条件搜索页面的标题和描述(
<title>和<meta name="description">)最好能动态生成,包含用户搜索的关键词,以利于 SEO,你可以在search_list.htm中通过{dede:global name='keyword'/}来实现。 - 性能:当数据库中文章数量非常多时,多条件搜索可能会对数据库造成一定压力,确保你的数据库索引(特别是
typeid和senddate字段)是正常的。 - 安全性:我们使用了
is_numeric和(int)对输入参数进行了简单的过滤,这可以防止大部分的 SQL 注入风险,在生产环境中,可以考虑使用更高级的过滤或预处理语句。
通过以上三个步骤,你就可以在 DedeCMS 中成功实现一个功能完善的多条件搜索了,这个方法稳定、兼容性好,且不依赖于额外的插件,是官方推荐的最佳实践。
