PHP实现敏感词过滤系统

时间:2022-06-01 18:29:42

原文地址:PHP实现敏感词过滤系统

安装说明

  1. 安装PHP扩展 trie_filter,安装教程 http://blog.41ms.com/post/39.html

  2. 安装PHP扩展 swoole,安装教程 http://www.swoole.com/


代码说明

1、敏感词库维护更新脚本:

reload_dict.php,提供自动更新字典库到trie-tree文件的过程

PHP
<?php

// 设置内存
ini_set('memory_limit', '128M');

// 读取敏感词字典库
$handle = fopen('dict.txt', 'r');

// 生成空的trie-tree-filter
$resTrie = trie_filter_new();

while(! feof($handle)) {
$item = trim(fgets($handle));

if (empty($item)) {
continue;
}

// 把敏感词逐个加入trie-tree
trie_filter_store($resTrie, $item);
}

// 生成trie-tree文件
$blackword_tree = 'blackword.tree';

trie_filter_save($resTrie, $blackword_tree);


2、trie树对象获取工具类

FilterHelper.php,提供获取trie-tree对象,避免重复生成trie-tree对象和保证tree文件与敏感词库的同步更新

PHP
<?php
/**
* 过滤器助手
*
* getResTrie 提供trie-tree对象;
* getFilterWords 提取过滤出的字符串
*
* @author W.Y.P (wangyupeng@jiayuan.com)
*/



class FilterHelper
{

// trie-tree对象
private static $_resTrie = null;
// 字典树的更新时间
private static $_mtime = null;


/**
* 防止初始化
*/

private function __construct() {}


/**
* 防止克隆对象
*/

private function __clone() {}


/**
* 提供trie-tree对象
*
* @param $tree_file 字典树文件路径
* @param $new_mtime 当前调用时字典树的更新时间
* @return null
*/

static public function getResTrie($tree_file, $new_mtime) {

if (is_null(self::$_mtime)) {
self::$_mtime = $new_mtime;
}

if (($new_mtime != self::$_mtime) || is_null(self::$_resTrie)) {
self::$_resTrie = trie_filter_load($tree_file);
self::$_mtime = $new_mtime;

// 输出字典文件重载时间
echo date('Y-m-d H:i:s') . "\tdictionary reload success!\n";
}

return self::$_resTrie;
}


/**
* 从原字符串中提取过滤出的敏感词
*
* @param $str 原字符串
* @param $res 1-3 表示 从位置1开始,3个字符长度
* @return array
*/

static public function getFilterWords($str, $res)
{
$result = array();
foreach ($res as $k => $v) {
$word = substr($str, $v[0], $v[1]);

if (!in_array($word, $result)) {
$result[] = $word;
}
}

return $result;
}
}


3、对外提供过滤HTTP访问接口

filter.php,使用swool,对外提交过滤接口访问

PHP
<?php

// 设置脚本最大运行内存,根据字典大小调整
ini_set('memory_limit', '512M');

// 设置时区
date_default_timezone_set('Asia/Shanghai');

// 加载助手文件
require_once('FilterHelper.php');

// http服务绑定的ip及端口
$serv = new swoole_http_server("182.92.177.16", 9502);


/**
* 处理请求
*/

$serv->on('Request', function($request, $response) {

// 接收get请求参数
$content = isset($request->get['content']) ? $request->get['content']: '';

$result = '';

if (!empty($content)) {

// 字典树文件路径,默认当时目录下
$tree_file = 'blackword.tree';

// 清除文件状态缓存
clearstatcache();

// 获取请求时,字典树文件的修改时间
$new_mtime = filemtime($tree_file);

// 获取最新trie-tree对象
$resTrie = FilterHelper::getResTrie($tree_file, $new_mtime);

// 执行过滤
$arrRet = trie_filter_search_all($resTrie, $content);

// 提取过滤出的敏感词
$a_data = FilterHelper::getFilterWords($content, $arrRet);

$result = json_encode($a_data);
}

// 定义http服务信息及响应处理结果
$response->cookie("User", "W.Y.P");
$response->header("X-Server", "W.Y.P WebServer(Unix) (Red-Hat/Linux)");
$response->header('Content-Type', 'Content-Type: text/html; charset=utf-8');
$response->end($result);
});

$serv->start();


测试效果

词库内容:

PHP实现敏感词过滤系统

接口响应过滤结果:

PHP实现敏感词过滤系统

尝试更新敏感词库,接口程序已自动加载最新敏感词库,保证过滤效果

PHP实现敏感词过滤系统

ab测试结果

词库:200W敏感词

服务器配置(CPU:1核内存:1024 MB;带宽:1Mbps

PHP实现敏感词过滤系统