在亵渎表中搜索单词时,所有单词都会被标记

时间:2015-02-20 18:39:14

标签: php mysql optimization

我的网站上有一个留言簿/评论系统的亵渎数据库。 它允许您输入,您的姓名,电子邮件,消息和我自己的CAPTCHA事物。其中名称,消息被公开显示,并且由于它是公开的,因此适度是重要的。

我希望PHP在收到消息时处理该消息:

  1. 将邮件转换为单词列表。
  2. 遍历数组中的每个单词并执行命令/功能。该命令应检查当前单词是否在数据库中
  3. 如果它在DB str_replace($bad_word, "[EXPLICIT]", $message)中,则转到下一个单词并重复
  4. 到目前为止,我有这段代码,其中$message是用户消息:

    $words_in_msg = explode(' ', $message);
    
            foreach($words_in_msg as &$word) {
                $res = mysqli_query($con,"
                    SELECT * FROM `badwords` WHERE `word` = '".$word."'
                ");
                var_dump($res);
                $num = mysqli_num_rows($res);
                if ($num !== 0) {
                    $message = str_replace($word, "[EXPLICIT]", $message);
                }
            }
    

    此代码在很大程度上起作用,因为它将列出$message中的所有单词,并且它将连接到数据库。但是在执行SQL命令之后出现了问题。我尝试过使用var_dump($res)得到了一个结果......但这不是我想要的结果。 This就是我得到的。

    我真正需要做的只是在数据库中的单词替换它。

    作为一个子问题,还有另一种更优化的方法来执行相同的功能吗?考虑到有超过1300个字要扫描,我不确定这是否会太慢。

2 个答案:

答案 0 :(得分:2)

我有一些如何优化此功能的提示:

  1. 使用array_unique限制要检查的字数:$words_in_msg = array_unique(explode(' ', $message));

  2. 只运行一次查询,然后获取所有错误单词的数组。所以,将它移到循环之外。

  3. 在循环查看单词数组之前,先执行array_intersect。如果结果数组为空,则可以停在那里,因为没有坏词。

  4. 如果有错误的单词,您可以使用当前循环,但不是每次都使用运行查询:

    foreach($ words_in_msg as $ word){   if(in_array($ word,$ aryBadWords){     $ message = str_replace($ word," [EXPLICIT]",$ message);   } }

  5. 或者,您可以使用单个正则表达式来执行所有替换

    $regex = '/(' . implode('|', $words_in_msg) . ')/i';
    $message = preg_replace($regex, '[EXPLICIT]', $message);
    

    不对每个单词运行查询都会有很大改进。

答案 1 :(得分:0)

您在sql查询中的concat运算符之间缺少空格,因此不是

SELECT * FROM `badwords` WHERE `word` = '".$word."

您可以使用

SELECT * FROM badwords WHERE word = '". $word ."