本文目录导读:

在PHP项目中处理敏感词过滤,常见的方法有以下几种,从简单到高效:
简单字符串替换(适用于少量敏感词)
function simpleFilter($text, $sensitiveWords) {
foreach ($sensitiveWords as $word) {
$text = str_replace($word, '***', $text);
}
return $text;
}
// 使用示例
$words = ['敏感词1', '敏感词2'];
$text = '这是一段包含敏感词1的文本';
echo simpleFilter($text, $words);
正则表达式过滤(更灵活)
function regexFilter($text, $sensitiveWords) {
$pattern = '/(' . implode('|', array_map('preg_quote', $sensitiveWords)) . ')/u';
return preg_replace($pattern, '***', $text);
}
// 使用示例
$text = '包含敏感词1和敏感词2的文本';
echo regexFilter($text, $words);
高效方案:Trie树(字典树)
这是处理大量敏感词时的最佳方案,适合生产环境:
class SensitiveFilter {
private $trie = [];
// 构建Trie树
public function addWords($words) {
foreach ($words as $word) {
$node = &$this->trie;
$len = mb_strlen($word);
for ($i = 0; $i < $len; $i++) {
$char = mb_substr($word, $i, 1);
if (!isset($node[$char])) {
$node[$char] = [];
}
$node = &$node[$char];
}
$node['end'] = true; // 标记结束
}
}
// 过滤敏感词
public function filter($text, $replaceChar = '*') {
$result = '';
$textLen = mb_strlen($text);
$i = 0;
while ($i < $textLen) {
$match = $this->findMatch($text, $i);
if ($match !== false) {
$result .= str_repeat($replaceChar, mb_strlen($match));
$i += mb_strlen($match);
} else {
$result .= mb_substr($text, $i, 1);
$i++;
}
}
return $result;
}
private function findMatch($text, $start) {
$node = $this->trie;
$match = '';
for ($i = $start; $i < mb_strlen($text); $i++) {
$char = mb_substr($text, $i, 1);
if (!isset($node[$char])) {
return $match ? $match : false;
}
$match .= $char;
$node = $node[$char];
if (isset($node['end'])) {
return $match;
}
}
return false;
}
}
// 使用示例
$filter = new SensitiveFilter();
$filter->addWords(['敏感词1', '敏感词2', '敏感词']);
$text = '这是一段包含敏感词1和敏感词2的文本';
echo $filter->filter($text);
使用扩展库(推荐生产环境)
使用 swoole 扩展(性能最好)
// 安装:pecl install swoole
$filter = new \Swoole\Filter();
$filter->setDict(['敏感词1', '敏感词2']);
$result = $filter->exec('包含敏感词的文本');
使用 trie_filter 扩展
// 安装:pecl install trie_filter
$tree = trie_filter_new();
foreach ($words as $word) {
trie_filter_store($tree, $word);
}
trie_filter_save($tree, 'sensitive.dic');
// 使用时加载
$tree = trie_filter_load('sensitive.dic');
$result = trie_filter_search($tree, '文本内容');
完整的生产环境方案
class SensitiveWordFilter {
private $trie = [];
private $filePath;
public function __construct($filePath = null) {
$this->filePath = $filePath ?: __DIR__ . '/sensitive_words.txt';
$this->loadFromFile();
}
// 从文件加载敏感词
private function loadFromFile() {
if (file_exists($this->filePath)) {
$words = file($this->filePath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$this->addWords($words);
}
}
// 添加单个词
public function addWord($word) {
$word = trim($word);
if (empty($word)) return;
$node = &$this->trie;
$len = mb_strlen($word);
for ($i = 0; $i < $len; $i++) {
$char = mb_substr($word, $i, 1);
if (!isset($node[$char])) {
$node[$char] = [];
}
$node = &$node[$char];
}
$node['end'] = true;
}
// 批量添加
public function addWords($words) {
foreach ($words as $word) {
$this->addWord($word);
}
}
// 检查是否包含敏感词
public function containsSensitive($text) {
$textLen = mb_strlen($text);
for ($i = 0; $i < $textLen; $i++) {
$match = $this->findMatch($text, $i);
if ($match !== false) {
return true;
}
}
return false;
}
// MySQL 版本(适合大量数据)
public function saveToDatabase($pdo) {
$words = json_encode($this->trie);
$sql = "INSERT INTO sensitive_config (`type`, `content`) VALUES ('trie', ?)
ON DUPLICATE KEY UPDATE `content` = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$words, $words]);
}
// 从数据库加载
public function loadFromDatabase($pdo) {
$sql = "SELECT content FROM sensitive_config WHERE type = 'trie' LIMIT 1";
$stmt = $pdo->query($sql);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if ($row) {
$this->trie = json_decode($row['content'], true);
}
}
}
// 生产环境使用示例
$filter = new SensitiveWordFilter('/path/to/sensitive_words.txt');
$text = $_POST['content'];
if ($filter->containsSensitive($text)) {
echo json_encode(['code' => 1, 'msg' => '包含敏感词']);
} else {
echo json_encode(['code' => 0, 'msg' => $filter->filter($text)]);
}
最佳实践建议
存储方式
- 小项目:保存在文本文件或数据库配置表中
- 大项目:使用Redis等缓存,减少IO开销
- 分布式:使用配置中心统一管理
性能优化
- 缓存Trie树:序列化后缓存到Redis
- 分片处理:大文本分段过滤
- 异步处理:使用消息队列异步过滤
- 静态化:生成过滤结果,减少实时计算
注意事项
- Unicode处理:使用
mb_*函数处理字符串 - 性能监控:记录过滤耗时,监控异常
- 更新机制:支持热更新敏感词列表
- 多语言支持:处理中英文混合情况
更复杂的场景处理
// 处理变体(如使用特殊字符绕过)
function antiEvasion($text) {
// 替换常见变体
$replacements = [
'/[1lI]/' => 'l', // 1和l的替换
'/[0oO]/' => 'o', // 0和o的替换
'/[@]/' => 'a', // @替换a
'/[\\x{3000}]/u' => '', // 全角空格
];
return preg_replace(array_keys($replacements), array_values($replacements), $text);
}
根据项目规模和性能要求选择合适的方案,建议在开发环境测试后再部署到生产环境。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播