下面我将为你提供一个详细、完整的步骤指南,分为两种主要方法:

- 使用织梦的“高级搜索”功能(推荐,更规范)
- 直接在自定义表单模板中编写搜索(更灵活,但需要手动处理分页等)
准备工作:以一个“留言反馈”表单为例
假设你已经创建了一个名为 dede_addonfeedback 的自定义表单(在后台“核心” -> “自定义表单”中创建),它包含以下字段:
id(主键,自增)uname(姓名,textinput)company(公司,textinput)tel(电话,textinput)email(邮箱,textinput)msg(留言内容,textarea)dtime(提交时间,datetime)
我们的目标是实现一个搜索框,可以根据uname、company、msg这三个字段进行关键词搜索。
使用织梦的“高级搜索”功能(推荐)
这种方法的好处是能直接利用织梦内置的搜索框架,自动处理分页、高亮、搜索结果页模板等,非常规范。
步骤 1:在自定义表单列表页添加搜索框
打开你的自定义表单列表页模板文件,通常是 plus/list.php 或者你自定义的模板文件(templets/plus/your_form_list.htm),为了清晰,我们创建一个独立的模板文件 templets/plus/feedback_search.htm。

在 feedback_search.htm 中,添加搜索表单:
<form name="search" action="/plus/search.php" method="get">
<!-- 隐藏字段,指定搜索模型为我们的自定义表单 -->
<input type="hidden" name="kwtype" value="0" />
<input type="hidden" name="searchtype" value="custom" />
<input type="hidden" name="typeid" value="1" /> <!-- typeid可以任意设置,但必须有 -->
<!-- 关键词输入框 -->
<input type="text" name="q" placeholder="请输入姓名、公司或留言内容..." />
<!-- 搜索按钮 -->
<button type="submit">搜索</button>
</form>
代码解释:
action="/plus/search.php":织梦的搜索程序入口。name="searchtype" value="custom":这是关键,告诉织梦这是一个“自定义”搜索,而不是搜索文章或产品。name="q":这是用户输入的关键词,织梦会自动获取这个值。
步骤 2:修改 plus/search.php 文件
这是实现自定义搜索的核心,我们需要修改 search.php,让它能识别并查询我们的自定义表单。
- 打开
/plus/search.php文件。 - 找到处理搜索类型的关键代码段。 大约在文件的第 60-80 行,你会看到
switch($searchtype)语句。 - 在
switch语句中添加case 'custom':分支。
在 switch($searchtype) 中添加如下代码:

// 在 switch($searchtype) 语句块内添加
case 'custom':
// 1. 获取关键词并处理
$keyword = trim($q);
if (empty($keyword)) {
ShowMsg('请输入搜索关键词!', '-1');
exit();
}
// 2. 设置搜索的表前缀和字段
// 注意:这里需要根据你的实际表名和要搜索的字段进行修改
$tablepre = $dsql->GetTablePrefix(); // 获取表前缀,如 'dede_'
$query = "SELECT * FROM `{$tablepre}addonfeedback` WHERE "; // 替换为你的自定义表名
// 3. 构建搜索条件
// 使用 CONCAT 函数将多个字段拼接成一个字符串进行搜索,实现多字段模糊匹配
$search_fields = array('uname', 'company', 'msg'); // 定义要搜索的字段
$like_conditions = array();
foreach ($search_fields as $field) {
$like_conditions[] = "`$field` LIKE '%$keyword%'";
}
$query .= implode(' OR ', $like_conditions);
// 4. 执行查询并获取结果
$dsql->SetQuery($query);
$dsql->Execute('fb');
$items = array();
while ($row = $dsql->GetArray('fb')) {
$items[] = $row;
}
// 5. 设置模板变量,并显示搜索结果页
$tempfile = $cfg_basedir.$cfg_templets_dir."/plus/search_result.htm";
$GLOBALS['totalresult'] = count($items); // 总结果数
$GLOBALS 'searchpage'] = ''; // 分页变量,这里我们先不处理分页
// 将结果数组传递给模板
$GLOBALS['arr'] = $items;
// 引入并解析搜索结果模板
include($tempfile);
exit();
break;
代码解释:
$tablepre:自动获取数据库表前缀,避免硬编码。{$tablepre}addonfeedback:替换成你的自定义表名。$search_fields:定义一个数组,包含所有需要搜索的字段名。LIKE '%$keyword%':标准的SQL模糊查询语法。implode(' OR ', $like_conditions):将多个字段的条件用OR连接起来,实现“任意字段匹配”。$GLOBALS['arr'] = $items;:将查询到的结果数组存入全局变量,供模板调用。$tempfile = ...:指定搜索结果要使用的模板文件。
步骤 3:创建搜索结果页模板
在 templets/plus/ 目录下创建一个名为 search_result.htm 的文件,这个文件用来展示搜索结果。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">搜索结果</title>
</head>
<body>
<h1>搜索结果</h1>
<!-- 显示搜索关键词和结果数量 -->
<p>搜索关键词:<strong>{dede:global.q/}</strong>,共找到 <strong>{dede:global.totalresult/}</strong> 条结果。</p>
<!-- 循环输出搜索结果 -->
{dede:global name='arr' function='print_r'/}
<!-- 上面的这行代码是用来调试的,它会直接打印出 $arr 数组的内容,你可以先加上它,看看数据结构,然后替换成下面的循环代码。 -->
<!-- 正确的循环输出方式 -->
<table border="1" width="100%">
<tr>
<th>姓名</th>
<th>公司</th>
<th>电话</th>
<th>留言内容</th>
<th>提交时间</th>
</tr>
{dede:global name='arr'}
<tr>
<td>[field:uname/]</td>
<td>[field:company/]</td>
<td>[field:tel/]</td>
<td>[field:msg function='cn_substr(@me, 50)'/]</td> <!-- 截取留言内容前50个字符 -->
<td>[field:dtime function='MyDate("Y-m-d H:i:s", @me)'/]</td>
</tr>
{/dede:global}
</table>
<!-- 注意:上面的 {dede:global name='arr'} ... {/dede:global} 是一个自定义标签循环,需要你修改 /include/taglib/global.lib.php 文件来支持。
更简单直接的方法是直接用PHP循环,但这不符合织梦模板规范。 -->
<!-- 为了简单起见,我们直接在模板里写PHP代码(不推荐,但快速实现) -->
<?php
if (is_array($GLOBALS['arr'])) {
foreach ($GLOBALS['arr'] as $field) {
echo "<tr>";
echo "<td>".$field['uname']."</td>";
echo "<td>".$field['company']."</td>";
echo "<td>".$field['tel']."</td>";
echo "<td>".cn_substr($field['msg'], 50)."</td>";
echo "<td>".MyDate('Y-m-d H:i:s', $field['dtime'])."</td>";
echo "</tr>";
}
}
?>
</body>
</html>
注意: 直接在模板中写PHP代码 (<?php ... ?>) 是一种快速实现的方式,但会破坏模板的封装性,更规范的方法是扩展织梦标签,但对于快速实现,这是可行的。
直接在自定义表单模板中编写搜索
这种方法更直接,不需要修改 search.php,但所有逻辑(分页、排序等)都需要自己处理。
步骤 1:修改列表页模板(如 templets/plus/feedback_list.htm)
在列表页的头部添加搜索表单。
<form name="myform" action="{dede:global.cfg_cmspath/}/plus/feedback_list.php" method="get">
<input type="hidden" name="tid" value="{dede:global.tid/}" /> <!-- 保持当前表单ID -->
<input type="text" name="keyword" placeholder="输入关键词搜索..." value="{dede:global.keyword/}" />
<button type="submit">搜索</button>
</form>
<hr>
<!-- 原有的列表内容 -->
{dede:list pagesize='10'}
<h3>[field:uname/] - [field:company/]</h3>
<p>[field:msg/]</p>
<p>时间:[field:dtime function="MyDate('Y-m-d H:i:s', @me)"/]</p>
<hr>
{/dede:list}
{dede:pagelist listsize='5'/}
步骤 2:修改列表处理程序(plus/list.php)
打开 /plus/list.php 文件,找到获取 tid 的地方,在其后添加获取 keyword 的逻辑,并修改SQL查询语句。
-
获取关键词变量: 在
$tid = isset($tid) && is_numeric($tid) ? $tid : 0;这类代码附近,添加:$keyword = isset($keyword) ? trim($keyword) : '';
-
修改SQL查询语句: 找到类似
$cquery = "SELECT * FROM{$tablepre}addonfeedbackWHERE arcrank > -1 ORDER BY id DESC";的代码。 修改为:// 基础查询 $cquery = "SELECT * FROM `{$tablepre}addonfeedback` WHERE 1=1"; // 如果有关键词,则添加搜索条件 if (!empty($keyword)) { $cquery .= " AND (`uname` LIKE '%$keyword%' OR `company` LIKE '%$keyword%' OR `msg` LIKE '%$keyword%')"; } // 添加排序 $cquery .= " ORDER BY id DESC"; -
传递关键词到模板: 在
include($tempfile);之前,添加:$GLOBALS['keyword'] = $keyword;
步骤 3:处理分页
{dede:pagelist/} 标签需要总记录数才能正常工作,我们需要手动计算总记录数。
在修改SQL查询的地方,添加一个计算总数的查询:
// ... 在修改 $cquery 之后 ...
// 计算总记录数
$count_query = "SELECT COUNT(*) AS total FROM `{$tablepre}addonfeedback` WHERE 1=1";
if (!empty($keyword)) {
$count_query .= " AND (`uname` LIKE '%$keyword%' OR `company` LIKE '%$keyword%' OR `msg` LIKE '%$keyword%')";
}
$row = $dsql->GetOne($count_query);
$GLOBALS['TotalResult'] = $row['total'];
// 设置分页
$pagesize = 10;
$TotalPage = ceil($GLOBALS['TotalResult'] / $pagesize);
if ($pagenow > $TotalPage) $pagenow = $TotalPage;
$limitstart = ($pagenow - 1) * $pagesize;
// 将 limit 添加到主查询
$cquery .= " LIMIT $limitstart, $pagesize";
// ... 后续执行查询 ...
总结与对比
| 特性 | 方法一 (高级搜索) | 方法二 (直接修改) |
|---|---|---|
| 实现难度 | 中等,需要修改核心文件 search.php |
中等,需要修改 list.php 和模板 |
| 规范性 | 高,符合织梦架构,代码复用性好 | 低,逻辑耦合在列表页,不易复用 |
| 分页处理 | 自动,由织梦搜索框架完成 | 手动,需要自己计算总数和分页 |
| 结果页 | 独立模板 (search_result.htm),清晰 |
与列表页共用一个模板 (list.htm) |
| 推荐度 | 强烈推荐,特别是对于需要复杂搜索和独立结果页的场景 | 适用于简单、独立的列表页内搜索,快速实现 |
对于大多数项目,方法一是更优的选择,因为它更规范、更易于维护,并且能更好地利用织梦自身的功能,虽然修改核心文件听起来有些“危险”,但只要操作前备份好文件,就是完全可行的。
