PHP DFA算法实现敏感词过滤包 php-dfa-sensitive

PHP学习教程 2022年11月3日 69

好不容易做个网站上线了,结果被一些别有用心的人灌水,发垃圾广告,垃圾评论,导致一些不该出现的词出现,往往出现这个,我们需要在后台不断的审核,删除,若是全部用人来做的话,想想这个
工作量都让人头疼,我们通常的做法是用程序过滤一部分,在加人工审核,当然程序若是能过滤掉100%是最好的,但是程序过滤的永远是第一次发生后的,预知就有点无能为力了。

DFA算法(确定有穷自动机)

安装包地址:https://packagist.org/packages/lustre/php-dfa-sensitive

github地址:https://github.com/FireLustre/php-dfa-sensitive

安装扩展

composer require lustre/php-dfa-sensitive

引人

use DfaFilter\SensitiveHelper;

调用

1、数组调用

$wordData = array(
'小秘',
'小李',
'小红',
'小红红',
'小莉莉',
......
);
$handle = SensitiveHelper::init()->setTree($wordData);

2、文件调用

$wordFilePath = 'data/words.txt'; //敏感词文件,文件中每个词一行
$handle = SensitiveHelper::init()->setTreeByFile($wordFilePath);

3、检测是否有敏感词

$islegal = $handle->islegal($content);

4、敏感词过滤

// 敏感词替换为*为例(会替换为相同字符长度的*)
$filterContent = $handle->replace($content, '*', true);
// 或敏感词替换为***为例
$filterContent = $handle->replace($content, '***');

5、标记敏感词

$markedContent = $handle->mark($content, '<mark>', '</mark>');

6、获取文字中的敏感词

// 获取内容中所有的敏感词
$sensitiveWordGroup = $handle->getBadWord($content);

// 仅且获取一个敏感词
$sensitiveWordGroup = $handle->getBadWord($content, 1);

封装为类

<?php
namespace App\Services;
use DfaFilter\SensitiveHelper;
class SensitiveWords
{
protected static $handle = null;
private function __construct()
{
}
private function __clone()
{
}
/**
* 获取实例
*/
public static function getInstance($word_path = [])
{
if (!self::$handle) {
//默认的一些敏感词库
$default_path = [
include_once('data/1.txt'), //敏感词文件
include_once('data/2.txt'),
include_once('data/3.txt'),
include_once('data/4.txt'),
];
$paths = array_merge($default_path, $word_path);
self::$handle = SensitiveHelper::init();
if (!empty($paths)) {
foreach ($paths as $path) {
self::$handle->setTreeByFile($path);
}
}
}
return self::$handle;
}
/**
* 检测是否含有敏感词
*/
public static function isLegal($content)
{
return self::getInstance()->islegal($content);
}
/**
* 敏感词过滤
*/
public static function replace($content, $replace_char = '', $repeat = false, $match_type = 1)
{
return self::getInstance()->replace($content, $replace_char, $repeat, $match_type);
}
/**
* 标记敏感词
*/
public static function mark($content, $start_tag, $end_tag, $match_type = 1)
{
return self::getInstance()->mark($content, $start_tag, $end_tag, $match_type);
}
/**
* 获取文本中的敏感词
*/
public static function getBadWord($content, $match_type = 1, $word_num = 0)
{
return self::getInstance()->getBadWord($content, $match_type, $word_num);
}
}

在项目中,使用 SensitiveWords::getBadWord() 来获取文本中是否有敏感词。

$bad_word = SensitiveWords::getBadWord($content);
if (!empty($bad_word)) {
throw new \Exception('包含敏感词:' . current($bad_word));
}

对于网站的敏感词,我们总是在与攻击者斗智斗勇,上面的是一种过滤的算法,不一定是最好的,我们往往还需要结合正则表达式,字符串过滤,火星文过滤等等技术手段,减少这方面词的出现。

存在问题

如果单纯只加入关键字匹配,用户反过滤的方法五花八门,包括中间加入空格或者其他标点符号。

例子

敏感词:扣扣

用户处理后:
扣 扣
扣,扣
扣@扣
扣1扣
这时候代码的正则匹配就可能匹配不出来。

解决办法:

先对用户数据去除所有的标点符号和一些特殊字符,然后再进行敏感词判断。

$flag_arr=array('?','!','¥','(',')',':','‘','’','“','”','《','》',',','…','。','、','nbsp','】','【','~');
$content_filter=preg_replace('/\s/','',preg_replace("/[[:punct:]]/",'',strip_tags(html_entity_decode(str_replace($flag_arr,'',$content),ENT_QUOTES,'UTF-8'))));

下面是我找到的一些敏感词包,大家需要的可以去下载。

资源下载
PHP学习网
公众号回复“PHPER6239”获取下载!
请打开微信扫描右边的二维码回复关键字“PHPER6239”也可以微信直接搜索“PHP学习网”关注微信公众号获取。


关注微信公众号『PHP学习网

第一时间了解最新网络动态
关注博主不迷路~

PHP学习网:站内收集的部分资源来源于网络,若侵犯了您的合法权益,请联系我们删除!
分享到:
赞(3)

文章评论

您需要之后才可以评论
0点赞 0评论 收藏 QQ分享 微博分享

PHP学习网

PHP学习网