You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

foreach循环嵌套SQL查询出现重复结果,求有效去重方案

解决敏感词查询重复结果的问题

问题根源

你当前的逻辑是循环每个敏感词单独执行一次SQL查询,若某条聊天消息包含多个敏感词(例如同时包含"bad"和"badword"),这条消息会被多次查询返回,即使单条SQL用了SELECT DISTINCT,循环输出时仍会重复显示。

解决方案

方法1:一次性SQL查询(推荐,高效且安全)

将所有敏感词的匹配条件用OR拼接成单条SQL,只执行一次查询,从根源避免重复结果,同时解决原代码的SQL注入风险:

<?php
$bad_word = ["badword", "bad_word", "bad", "frick", "heck"];
// 构造每个敏感词对应的LIKE占位符
$placeholders = array_fill(0, count($bad_word), 'msg LIKE ?');
// 拼接WHERE条件
$whereClause = implode(' OR ', $placeholders);
// 预处理SQL语句
$stmt = $con->prepare("SELECT DISTINCT username, msg, date_log, time_log FROM chat_logs WHERE $whereClause");

// 为每个敏感词生成带通配符的参数
$params = array_map(function($word) {
    return "%$word%";
}, $bad_word);
// 绑定参数类型(所有参数都是字符串,用's'表示)
$types = str_repeat('s', count($params));
$stmt->bind_param($types, ...$params);

$stmt->execute();
$result = $stmt->get_result();

// 输出结果
while($bad_msg = mysqli_fetch_array($result)){
    echo '
    <div class="msg">
    <div class="msg-top">
    <p><b>'.$bad_msg['username'].'</b> '.$bad_msg['date_log'].' - '.$bad_msg['time_log'].'</p></div>';
    if(!empty($bad_msg['msg'])){
        echo '<span>'.$bad_msg['msg'].'</span>';
    }
    echo '</div>';
}
?>

方法2:PHP层面去重

如果不想修改SQL逻辑,可以在PHP中用数组存储结果时,通过唯一标识过滤重复记录:

<?php
$bad_word = ["badword", "bad_word", "bad", "frick", "heck"];
$uniqueResults = [];

foreach($bad_word as $word){
    $get_flags = $con->query("SELECT DISTINCT username, msg, date_log, time_log FROM chat_logs WHERE msg LIKE '%$word%'");
    while($bad_msg = mysqli_fetch_array($get_flags)){
        // 用消息内容+日期+时间生成唯一键,确保同一条消息只存一次
        $key = $bad_msg['msg'] . '_' . $bad_msg['date_log'] . '_' . $bad_msg['time_log'];
        $uniqueResults[$key] = $bad_msg;
    }
}

// 遍历去重后的结果输出
foreach($uniqueResults as $bad_msg){
    echo '
    <div class="msg">
    <div class="msg-top">
    <p><b>'.$bad_msg['username'].'</b> '.$bad_msg['date_log'].' - '.$bad_msg['time_log'].'</p></div>';
    if(!empty($bad_msg['msg'])){
        echo '<span>'.$bad_msg['msg'].'</span>';
    }
    echo '</div>';
}
?>

注意事项

  • 原代码直接将变量拼接进SQL存在SQL注入风险,方法1使用预处理语句彻底解决了这个问题,更推荐使用。
  • 方法1只需执行一次数据库查询,性能远优于循环多次查询的方式。

内容的提问来源于stack exchange,提问作者mysh randy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 14:25:22