- 修改核心文件(最直接,但升级会失效)
- 使用自定义函数(推荐,更灵活,升级不易失效)
修改核心文件(arc.searchview.class.php)
这是最直接的方法,通过修改织梦处理搜索结果的核心类文件来实现。
适用场景: 快速实现,不介意修改核心文件,且网站不经常进行织梦程序本身的升级。
操作步骤:
-
找到核心文件 打开你的织梦网站根目录,找到并打开以下文件:
/include/arc.searchview.class.php -
定位关键代码 在该文件中,找到
Query()函数,这个函数负责构建和执行最终的SQL查询语句,在函数内部,找到类似这样的代码段(通常在函数末尾):// ... // 在 arc.searchview.class.php 文件的 Query() 函数中 if($this->ChannelType > -1 && $this->ChannelType < 100) { // ... } else { $this->AddSql = " arc.title LIKE '%$this->keyword%' "; } // ... 其他代码 ... // 执行查询 $this->dsql->SetQuery($this->GetSql($this->searchArr)); $this->dsql->Execute('al'); // ...我们需要找到
GetSql()这个函数,它才是真正生成SQL语句的地方。 -
修改
GetSql()函数 在arc.searchview.class.php文件中找到GetSql()函数,你会看到它根据不同的条件(如频道、模型等)生成不同的SQL语句,我们需要修改的是默认的搜索SQL。找到处理“通用搜索”或“默认模型”的
else分支,通常是下面这个部分:// ... 在 GetSql() 函数中 ... else { $ordersql = " ORDER BY arc.sortrank DESC"; // 默认按排序值(权重)降序 // ... 或者可能是 ... // $ordersql = " ORDER BY arc.pubdate DESC"; // 这是默认的按发布时间降序 // ... $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 {$this->AddSql} $ordersql $limitSql"; }关键点:
$ordersql变量决定了排序方式。- 织梦文章表(
#@__archives)中的sortrank字段就是用来存储权重的。数值越大,权重越高。 DESC表示降序(从大到小),ASC表示升序(从小到大)。
-
进行修改 将
$ordersql的值修改为按sortrank(权重)排序。// 修改前 (可能是这样) // $ordersql = " ORDER BY arc.pubdate DESC"; // 修改后 (按权重降序) $ordersql = " ORDER BY arc.sortrank DESC";
如果你希望权重高的排在前面,就使用
DESC,如果你的逻辑是数值越小权重越高,则使用ASC。 -
保存并测试 保存修改后的
arc.searchview.class.php文件,然后清空一下网站缓存(后台-系统-清除缓存),再到前台进行搜索测试,你会发现搜索结果已经按照权重排序了。
使用自定义函数(推荐)
这种方法不修改核心文件,而是通过织梦的模板引擎机制,在搜索结果列表循环中手动进行排序,这是更规范、更安全的做法。
适用场景: 推荐所有用户使用,特别是对网站稳定性要求高、未来可能升级织梦程序的用户。
操作步骤:
-
准备数据(将结果存入数组) 打开你的搜索模板文件,默认路径是
/templets/default/search.htm。在搜索结果循环开始之前,你需要先获取所有结果,但不直接输出,而是将它们存入一个PHP数组中,织梦的搜索结果循环
{dede:list}或{dedarclist}在这个场景下不太好用,我们改用{dede:php}标签来手动处理。在
search.htm的{dede:loop}循环之前,添加如下代码:<!-- search.htm --> <div class="search-result"> {dede:php} // 1. 获取搜索结果对象 $searchService = new Search(); $searchService->Init(); $searchResult = $searchService->GetResult('al'); // 'al' 是结果集的别名 // 2. 将结果存入一个新数组,并提取权重 $items = array(); if(is_array($searchResult)) { foreach($searchResult as $row) { // 将权重作为数组的一个键,方便后面排序 $items[$row['id']] = $row; // 注意:$row['sortrank'] 就是权重值 } } // 3. 按权重(sortrank)对数组进行降序排序 // 使用 array_multisort 进行多维度排序 $sort = array(); foreach($items as $k => $item) { $sort[$k] = $item['sortrank']; } // array_multisort 的参数:排序的数组, 排序方式, 排序类型, 要排序的主数组 array_multisort($sort, SORT_DESC, $items); // 4. 将排序后的数组重新赋值给 $searchResult,供下面的循环使用 $GLOBALS['searchResult'] = $items; {/dede:php} <!-- 5. 开始循环输出排序后的结果 --> {dede:loop table=' #@__archives ' sort='' row='10' if=''} <!-- 注意:这里的循环方式已经变了,我们实际上是在循环上面处理好的PHP数组 --> <!-- 所以这个 {dede:loop} 可能不适用,我们需要换一种方式 --> <!-- 正确的循环方式应该是: --> {dede:php} if(is_array($GLOBALS['searchResult']) && count($GLOBALS['searchResult']) > 0) { foreach($GLOBALS['searchResult'] as $row) { // 在这里输出每一个搜索结果项 // 注意:这里需要输出HTML结构,而不是使用织梦标签 ?> <div class="result-item"> <a href="<?php echo $row['arcurl']; ?>"><?php echo $row['title']; ?></a> <p><?php echo $row['description']; ?></p> </div> <?php } } {/dede:php} {/dede:loop} </div>上面的代码有点复杂,我们来简化一下,更清晰的做法:
简化版
search.htm代码:<!-- search.htm --> <div class="search-result"> {dede:php} // 1. 获取原始搜索结果 $dsql = $GLOBALS['dsql']; $keyword = trim($_REQUEST['q']); $typeid = isset($_REQUESTtypeid) ? intval($_REQUEST['typeid']) : 0; $addsql = " WHERE arc.title LIKE '%$keyword%' "; if($typeid > 0) { $addsql .= " AND arc.typeid = $typeid "; } // 2. 查询所有符合条件的文章,并按权重排序 $sql = "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 $addsql ORDER BY arc.sortrank DESC"; // <-- 关键:直接在SQL里按权重排序 $dsql->SetQuery($sql); $dsql->Execute('s'); // 3. 循环输出结果 while($row = $dsql->GetArray('s')) { // 获取文章URL $row['arcurl'] = GetFileUrl($row['id'],$row['typeid'],$row['senddate'],$row['title'],$row['ismake'],$row['arcrank'],$row['namerule'],$row['typedir'],$row['money']); // 输出HTML echo '<div class="result-item">'; echo '<h3><a href="'.$row['arcurl'].'" target="_blank">'.$row['title'].'</a></h3>'; echo '<p class="info">'.$row['description'].'</p>'; echo '</div>'; } if($dsql->GetTotalRow('s') == 0) { echo '<div class="result-empty">抱歉,没有找到与 "<strong>'.$keyword.'</strong>" 相关的内容。</div>'; } {/dede:php} </div> -
保存并测试 保存修改后的
search.htm文件,清空网站缓存,然后测试搜索功能,你会发现结果已经按照权重排序了。
总结与对比
| 特性 | 修改核心文件 | 自定义函数 |
|---|---|---|
| 优点 | 实现简单,直接。 一次修改,全局生效。 |
安全,不破坏核心文件,不影响程序升级。 灵活性极高,可以完全自定义搜索结果的显示逻辑。 逻辑清晰,修改和排查问题都在模板文件中。 |
| 缺点 | 不安全,覆盖核心文件,升级织梦时会被覆盖。 修改范围大,不易排查问题。 可能影响其他依赖该文件的功能。 |
代码量稍多,需要一定的PHP基础。 每个搜索模板都需要修改(如果不想全局生效的话)。 |
| 推荐度 | ⭐⭐ (不推荐) | ⭐⭐⭐⭐⭐ (强烈推荐) |
对于长期维护的网站,强烈建议使用 方法二(自定义函数),虽然它需要你写一些PHP代码,但它带来的稳定性和安全性是方法一无法比拟的,方法一只适合于临时测试或非常小型的、不进行程序升级的个人项目。
