好不容易做个网站上线了,结果被一些别有用心的人灌水,发垃圾广告,垃圾评论,导致一些不该出现的词出现,往往出现这个,我们需要在后台不断的审核,删除,若是全部用人来做的话,想想这个 工作量都让人头疼,我们通常的做法是用程序过滤一部分,在加人工审核,当然程序若是能过滤掉100%是最好的,但是程序过滤的永远是第一次发生后的,预知就有点无能为力了。
DFA算法(确定有穷自动机)
安装包地址:https://packagist.org/packages/lustre/php-dfa-sensitive
github地址:https://github.com/FireLustre/php-dfa-sensitive
安装扩展
代码语言:javascript复制composer require lustre/php-dfa-sensitive
引人
代码语言:javascript复制use DfaFilterSensitiveHelper;
调用
1、数组调用
代码语言:javascript复制$wordData = array(
'小秘',
'小李',
'小红',
'小红红',
'小莉莉',
......
);
$handle = SensitiveHelper::init()->setTree($wordData);
2、文件调用
代码语言:javascript复制$wordFilePath = 'data/words.txt'; //敏感词文件,文件中每个词一行
$handle = SensitiveHelper::init()->setTreeByFile($wordFilePath);
3、检测是否有敏感词
代码语言:javascript复制$islegal = $handle->islegal($content);
4、敏感词过滤
代码语言:javascript复制// 敏感词替换为*为例(会替换为相同字符长度的*)
$filterContent = $handle->replace($content, '*', true);
// 或敏感词替换为***为例
$filterContent = $handle->replace($content, '***');
5、标记敏感词
代码语言:javascript复制$markedContent = $handle->mark($content, '<mark>', '</mark>');
6、获取文字中的敏感词
代码语言:javascript复制// 获取内容中所有的敏感词
$sensitiveWordGroup = $handle->getBadWord($content);
// 仅且获取一个敏感词
$sensitiveWordGroup = $handle->getBadWord($content, 1);
封装为类
代码语言:javascript复制<?php
namespace AppServices;
use DfaFilterSensitiveHelper;
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() 来获取文本中是否有敏感词。
代码语言:javascript复制$bad_word = SensitiveWords::getBadWord($content);
if (!empty($bad_word)) {
throw new Exception('包含敏感词:' . current($bad_word));
}
对于网站的敏感词,我们总是在与攻击者斗智斗勇,上面的是一种过滤的算法,不一定是最好的,我们往往还需要结合正则表达式,字符串过滤,火星文过滤等等技术手段,减少这方面词的出现。