- 高级搜索页面模板 (
search_advanced.htm): 用户看到的搜索表单界面。 - 处理搜索的 PHP 文件 (
search.php): 接收用户提交的搜索条件,并调用相应的函数进行数据库查询。 - 搜索结果页面模板 (
search.htm): 用于展示搜索结果的模板。
下面我将分步讲解如何创建和自定义一个功能完善的高级搜索页面。

(图片来源网络,侵删)
第一步:创建高级搜索页面模板 (search_advanced.htm)
这个模板负责展示一个复杂的搜索表单,让用户可以根据多个条件进行筛选。
文件位置
通常位于你的模板目录下,/templets/default/search_advanced.htm,如果这个文件不存在,你需要从系统默认模板中复制一份,或者自己创建。
模板代码示例
下面是一个功能比较丰富的高级搜索表单代码,你可以根据需要修改。
{dede:include filename="head.htm"/}
<!-- 高级搜索表单 -->
<div class="search-advanced">
<h2>高级搜索</h2>
<form name="formsearch" action="{dede:global.cfg_cmspath/}/search.php" method="get">
<input type="hidden" name="kwtype" value="1" /> <!-- 搜索类型,1为关键词搜索 -->
<div class="search-item">
<label for="keyword">关键词:</label>
<input type="text" name="q" id="keyword" size="30" placeholder="请输入搜索关键词" />
</div>
<div class="search-item">
<label>搜索范围:</label>
<select name="typeid">
<option value="0">所有栏目</option>
{dede:channel type='son' current=''}
<option value='{typeid}' {dede:if typeid='typeid'}selected{/dede:if}>{typename}</option>
{/dede:channel}
</select>
</div>
<div class="search-item">
<label>发布时间:</label>
<select name="searchtype">
<option value="all">所有时间</option>
<option value="week">最近一周</option>
<option value="month">最近一月</option>
<option value="year">最近一年</option>
<option value="day">lt;/option>
</select>
</div>
<div class="search-item">
<label>排序方式:</label>
<select name="orderby">
<option value="default">默认排序</option>
<option value="pubdate">发布时间</option>
<option value="hot">热度/点击量</option>
<option value="scores">评分</option>
</select>
</div>
<div class="search-item">
<label>自定义字段:</label>
<!-- 假设你有一个自定义字段叫 'writer' (作者) -->
<input type="text" name="writer" placeholder="作者" />
<!-- 假设你有一个自定义字段叫 'tag' (标签) -->
<input type="text" name="tag" placeholder="标签" />
</div>
<div class="search-btn">
<button type="submit">开始搜索</button>
</div>
</form>
</div>
{dede:include filename="foot.htm"/}
代码解析:
{dede:include filename="head.htm"/}和{dede:include filename="foot.htm"/}: 加载网站的头部和尾部模板。<form action="{dede:global.cfg_cmspath/}/search.php" method="get">: 表单提交地址是search.php,使用get方法提交,这样搜索条件会显示在 URL 中,方便分享和收藏。<input type="hidden" name="kwtype" value="1">: 这是一个固定参数,告诉search.php我们使用的是关键词搜索模式。{dede:channel type='son' current=''}: 这是一个循环标签,用于获取当前栏目的所有子栏目,并生成一个下拉选择框。typeid是栏目 ID,typename是栏目名称。name="q": 这是最重要的关键词输入框,search.php默认接收这个参数来执行搜索。name="typeid",name="searchtype",name="orderby": 这些都是自定义的参数名,search.php会根据这些参数来构建不同的 SQL 查询条件。name="writer",name="tag": 这些是自定义字段的搜索,你需要确保你的文章模型中存在这些字段,search.php能够处理它们。
第二步:修改处理搜索的 PHP 文件 (search.php)
search.php 是搜索功能的核心,默认的 search.php 功能比较简单,我们需要扩展它以支持高级搜索条件。
文件位置
/plus/search.php
修改思路
默认的 search.php 主要通过 if 语句处理 q (关键词)、typeid (栏目ID) 等几个基本参数,要实现高级搜索,我们需要:
- 获取所有参数:从
$_GET或$_POST中获取所有提交的搜索条件。 - 构建基础查询:使用
GetKeyword()等函数获取关键词,并构建WHERE子句的核心部分(如arc.title LIKE '%关键词%' OR arc.body LIKE '%关键词%')。 - 拼接附加条件:根据其他参数(如发布时间、排序、自定义字段)动态拼接
AND条件到WHERE子句中。 - 执行查询:将构建好的完整 SQL 语句交给
DedeSql或mysqli执行。 - 分页处理:调用
GetPageList()等函数处理分页逻辑。
修改示例代码
这是一个修改后的 search.php 核心逻辑示例,你可以参考它来修改你的文件。
// 引入必要的文件
require_once(dirname(__FILE__)."/../include/common.inc.php");
// 获取搜索参数
$keyword = trim($_GET['q']);
$typeid = isset($_GET['typeid']) && $_GET['typeid'] > 0 ? intval($_GET['typeid']) : 0;
$searchtype = isset($_GET['searchtype']) ? trim($_GET['searchtype']) : 'all';
$orderby = isset($_GET['orderby']) ? trim($_GET['orderby']) : 'default';
// 初始化查询条件
$where = " WHERE arc.arcrank > -1 "; // 只显示已审核的文章
// 1. 关键词搜索
if (!empty($keyword)) {
// 使用 DedeCMS 自带的函数处理关键词,支持多关键词
$keyword = GetSearchKeyWord($keyword);
$where .= " AND ($keyword) ";
}
// 2. 栏目搜索
if ($typeid > 0) {
$where .= " AND arc.typeid IN (SELECT id FROM `#@__arctype` WHERE id='$typeid' OR topid='$typeid') ";
}
// 3. 发布时间搜索
if ($searchtype != 'all') {
$ntime = time();
switch ($searchtype) {
case 'day':
$where .= " AND arc.senddate > $ntime - 86400 ";
break;
case 'week':
$where .= " AND arc.senddate > $ntime - 604800 ";
break;
case 'month':
$where .= " AND arc.senddate > $ntime - 2592000 ";
break;
case 'year':
$where .= " AND arc.senddate > $ntime - 31536000 ";
break;
}
}
// 4. 自定义字段搜索 (示例:搜索作者字段)
if (!empty($_GET['writer'])) {
$writer = addslashes($_GET['writer']);
$where .= " AND arc.writer LIKE '%$writer%' ";
}
// 5. 排序
$ordersql = '';
switch ($orderby) {
case 'hot':
$ordersql = " ORDER BY arc.click DESC ";
break;
case 'pubdate':
$ordersql = " ORDER BY arc.senddate DESC ";
break;
case 'scores':
$ordersql = " ORDER BY arc.scores DESC ";
break;
default:
$ordersql = " ORDER BY arc.id DESC ";
}
// 获取分页信息
$pagesize = 10; // 每页显示数量
$row = $dsql->GetOne("SELECT COUNT(*) AS dd FROM `#@__archives` $where");
$totalresult = $row['dd'];
$totalpage = ceil($totalresult / $pagesize);
// 获取当前页码
$page = isset($_GET['page']) && is_numeric($_GET['page']) ? intval($_GET['page']) : 1;
// 获取搜索结果列表
$sql = "SELECT arc.*,tp.typename,tp.corank,tp.isdefault,tp.typedir,tp.namerule,tp.moresite,tp.siteurl,tp.sitepath
FROM `#@__archives` arc
LEFT JOIN `#@__arctype` tp ON arc.typeid=tp.id
$where $ordersql
LIMIT " . ($page - 1) * $pagesize . ", $pagesize";
$dsql->SetQuery($sql);
$dsql->Execute('al');
$artlist = array();
while ($row = $dsql->GetArray('al')) {
$artlist[] = $row;
}
// 调用分页函数
$pagenav = GetPageList($totalresult, $pagesize, $page, "search.php?q=".urlencode($keyword)."&typeid=$typeid&searchtype=$searchtype&orderby=$orderby");
// 将变量传递给模板
$tpl->assign('keyword', $keyword);
$tpl->assign('artlist', $artlist);
$tpl->assign('page', $page);
$tpl->assign('totalresult', $totalresult);
$tpl->assign('pagenav', $pagenav);
// 指定搜索结果模板
$tpl->display('search.htm');
第三步:修改搜索结果页面模板 (search.htm)
这个模板负责展示 search.php 传递过来的搜索结果数据。
文件位置
通常位于你的模板目录下,/templets/default/search.htm。
模板代码示例
{dede:include filename="head.htm"/}
<div class="main">
<div class="path">
<span>您的位置:</span><a href='{dede:global.cfg_cmsurl/}/'>首页</a> > <a href='{dede:global.cfg_cmsurl/}/search.php'>搜索</a> > <strong>搜索结果</strong>
</div>
<!-- 搜索信息提示 -->
<div class="search-info">
<p>搜索 "<strong>{dede:global name='keyword'/}</strong>" 找到 <strong>{dede:global name='totalresult'/}</strong> 条结果</p>
</div>
<!-- 搜索结果列表 -->
<div class="result-list">
{dede:list pagesize='10'}
<div class="result-item">
<h3><a href="[field:arcurl/]" title="[field:title/]">[field:title function='cn_substr(@me, 30)'/]</a></h3>
<p class="info">
<span>栏目:[field:typename/]</span> |
<span>发布时间:[field:pubdate function='MyDate('Y-m-d', @me)'/]</span> |
<span>点击:[field:click/]</span>
</p>
<p class="intro">
[field:description function='cn_substr(@me, 150)'/]...
</p>
</div>
{/dede:list}
</div>
<!-- 分页导航 -->
<div class="page-nav">
{dede:pagelist listitem='index,pre,next,end,pageno' listsize='5'/}
</div>
</div>
{dede:include filename="foot.htm"/}
代码解析:
{dede:global name='keyword'/}: 显示用户搜索的关键词。{dede:global name='totalresult'/}: 显示搜索到的总结果数。{dede:list}: 这是 DedeCMS 的列表循环标签,它会循环输出search.php中查询到的$artlist数组。[field:arcurl/],[field:title/],[field:typename/]等: 这些是列表项的字段标签,用于显示文章的标题、链接、栏目等信息。{dede:pagelist}: 用于生成分页导航链接,它会自动使用search.php中设置的 URL 参数。
总结与注意事项
- 文件备份:在修改
search.php这样的核心文件之前,务必备份原文件! - 自定义字段:要在搜索中支持自定义字段,必须确保
search.php中的 SQL 查询包含了这些字段(arc.writer),并且你的文章模型中已经添加了这些字段。 - 安全:所有从用户端获取的数据(如
$_GET)都应该进行安全处理,例如使用addslashes()、intval()等,防止 SQL 注入,DedeCMS 的一些内置函数(如GetSearchKeyWord)已经做了一定的处理。 - 性能:复杂的搜索条件(特别是多个
LIKE查询)可能会对数据库造成较大压力,如果网站数据量很大,需要考虑优化数据库索引或使用更高级的搜索引擎(如 Elasticsearch)。 - 模板标签:确保在
search_advanced.htm和search.htm中使用的模板标签与你的 PHP 文件中传递的变量名一致。
通过以上三个步骤,你就可以创建一个功能强大且自定义程度很高的 DedeCMS 高级搜索页面了。
