dede如何实现多条件搜索功能?

99ANYc3cd6
预计阅读时长 28 分钟
位置: 首页 DEDE建站 正文

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

dede 多条件搜索
(图片来源网络,侵删)

下面我将分步为您讲解,并提供最常用、最稳妥的修改方法。


第一步:创建多条件搜索表单

这是用户交互的入口,我们需要一个包含多个输入框的下拉菜单或表单。

目标文件: templets/default/search.htm (这是默认的搜索模板,你可以根据你的模板路径进行修改) **

search.htm 文件中,找到默认的搜索表单,并将其修改为包含多个条件的表单。

dede 多条件搜索
(图片来源网络,侵删)

示例代码:

<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>

代码解释:

  1. action="{dede:global.cfg_cmspath/}/search.php": 表单提交的目标是 search.php 文件,这是 DedeCMS 处理搜索的核心文件。
  2. name="q": 这是默认的关键词输入框,search.php 会识别这个参数。
  3. name="typeid": 新增的栏目选择框。typeid 是 DedeCMS 内置的用于指定栏目 ID 的参数。
  4. name="time": 新增的时间范围选择框,这个参数 time 是 DedeCMS 自带支持的,用于限定文章的发布时间。
  5. {dede:channel type='self' row='10'}: 这是一个 DedeCMS 的标签,用于获取当前栏目及其子栏目的列表,方便用户选择。

第二步:修改搜索处理核心文件 search.php

这是实现多条件搜索逻辑的关键,我们需要修改 search.php,让它能够处理我们新增的 typeidtime 参数。

目标文件: /search.php

dede 多条件搜索
(图片来源网络,侵删)

修改步骤:

  1. 找到 search.php 文件。
  2. 找到获取搜索关键词的代码,通常是 $q = trim($_GET['q']);
  3. 在其下方,添加获取我们新增参数的代码。

修改后的 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();
}
?>

代码解释:

  1. 获取参数:我们通过 $_GET 获取 typeidtime,并进行简单的类型转换和安全性检查。
  2. 构建 $addquery:这是核心,我们初始化一个 $addquery 变量来存放额外的 SQL 查询条件。
    • 栏目条件:如果用户选择了栏目($typeid > 0),我们就将 typeid IN ($typeid) 添加到查询条件中。IN 关键字可以同时匹配多个栏目 ID。
    • 时间条件:如果用户选择了时间范围($keywordtime > 0),我们就计算出时间戳,并将 senddate > $ntime 添加到查询条件中。
  3. 组合 SQL:最终的查询语句 searchsql 在原有的 arc.title LIKE '%$q%' 基础上,通过 AND 连接了我们新加的 $addquery 条件。
  4. 调用函数$sp->GetArcLists($query); 这行代码会执行查询,并将结果传递给模板。

注意:上面的代码直接构建了 SQL 查询,更规范的做法是使用 DedeCMS 的 GetSonIds 函数来获取指定栏目及其所有子栏目的 ID,这样在搜索某个栏目时,其子栏目的文章也会被包含进来,你可以取消注释 $typeid = GetSonIds($typeid); 来实现这个功能。


第三步:修改搜索结果页模板 search.php 对应的模板文件

search.php 在执行时会调用一个模板文件来显示结果,默认情况下,它使用 templets/default/search.htm,但我们第一步已经修改了这个文件,所以我们需要为结果页创建一个新的模板,或者让结果页使用一个专门的模板文件。

使用独立的搜索结果模板(推荐)

  1. templets/default/ 目录下创建一个新文件,search_list.htm

  2. search.php 文件中,找到 $sp->GetArcLists($query); 这行代码,在它之前添加一行代码来指定模板文件:

    // 在 $sp->GetArcLists($query); 之前添加
    $sp->SetTemplet(templets('default/search_list.htm')); 
  3. 编辑 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}: 循环输出搜索到的文章列表,用法和列表页完全一样。

总结与注意事项

  1. 文件备份:在修改任何核心文件(如 search.php)之前,请务必备份原始文件,以防出错。
  2. SEO:多条件搜索页面的标题和描述(<title><meta name="description">)最好能动态生成,包含用户搜索的关键词,以利于 SEO,你可以在 search_list.htm 中通过 {dede:global name='keyword'/} 来实现。
  3. 性能:当数据库中文章数量非常多时,多条件搜索可能会对数据库造成一定压力,确保你的数据库索引(特别是 typeidsenddate 字段)是正常的。
  4. 安全性:我们使用了 is_numeric(int) 对输入参数进行了简单的过滤,这可以防止大部分的 SQL 注入风险,在生产环境中,可以考虑使用更高级的过滤或预处理语句。

通过以上三个步骤,你就可以在 DedeCMS 中成功实现一个功能完善的多条件搜索了,这个方法稳定、兼容性好,且不依赖于额外的插件,是官方推荐的最佳实践。

-- 展开阅读全文 --
头像
杭州织梦摄影工作室,如何织就你的独家梦境?
« 上一篇 04-21
Msgpack C语言如何高效使用?
下一篇 » 04-21

相关文章

取消
微信二维码
支付宝二维码

目录[+]