PHP自定义敏感词过滤函数仅首个词生效原因排查
代码失效原因说明
核心原因
你在处理第一个敏感词cat时,已经通过while(!feof($file))将words.txt的内容从头到尾读取完毕,此时文件指针会停在文件末尾。后续处理dog等其他词汇时,!feof($file)的判断结果直接为false,while循环完全不会执行,自然无法匹配到后续的敏感词。
其他隐藏问题
- 每次判断一个词汇都遍历读取一次文件的逻辑性能极低,敏感词数量多、输入文本长的情况下会严重拖慢执行速度
- 现有替换逻辑的下标计算存在偏移错误,处理末尾词汇时容易出现替换错位或者下标越界的问题
- 仅支持空格分隔的独立词汇匹配,敏感词和其他字符连用时无法识别,属于需求设计层面的限制,不属于本次bug的诱因
修复方案
如果不修改原有逻辑,仅解决本次匹配失效问题,只需要在while(!feof($file))前增加一行rewind($file),将文件指针重置到文件开头即可,但该方案性能较差,仅适合临时验证问题。
更合理的优化写法是提前将所有敏感词读取到数组中,后续直接查询数组匹配即可:
<?php function pfilter($text){ $result = ""; $word = ""; $length = strlen($text); // 提前一次性读取所有敏感词存入数组 $badWords = []; $file = fopen("words.txt", "r"); while(!feof($file)){ $line = trim(fgets($file)); if(!empty($line)) $badWords[] = $line; } fclose($file); for($i = 0; $i < $length; $i++){ $result .= $text[$i]; if($text[$i] != ' ') $word .= $text[$i]; if(($text[$i] == ' ' || $i == $length - 1) && $word != ' ' && !empty($word)){ if(in_array($word, $badWords)){ $wlength = strlen($word); $rlength = strlen($result); // 修正替换位置的偏移错误 $offset = ($text[$i] == ' ') ? 2 : 1; for($j = 1; $j <= $wlength; $j++){ $result[$rlength - $j - ($offset - 1)] = '*'; } } $word = ''; } } return $result; } echo pfilter("cat dog meow bark"); ?>
内容的提问来源于stack exchange,提问作者userx1234
相关产品推荐
相关产品推荐

