使用php扩展trie-tree,过滤敏感词

原文地址:http://blog.41ms.com/post/39.html

php扩展安装说明:

1.安装php扩展trie-tree,安装教程 http://blog.41ms.com/post/39.html
2.安装swoole扩展,安装教程 http://www.swoole.com/

代码说明:

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

/**
 * 词库维护更新.
 * Date: 2018/11/7
 * Time: 9:42
 */

// 设置内存
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文件与敏感词库的同步更新

/**
 * 过滤器助手.
 * getResTrie       提供trie-tree对象
 * getFilterWords   提取过滤出的字符串
 * Date: 2018/11/7
 * Time: 9:49
 */
class FilterHelper
{

    // trie-tree对象
    private static $_resTrie = null;

    // 字典树的更新时间
    private static $_mtime = null;



    /**
     * 方式初始化
     */
    public function __construct(){}


    /**
     * 防止克隆对象
     */
    public function __clone(){}



    /**
     * 提供trie-tree对象
     *
     * @param    string    $tree_file   字典文件树路径
     * @param    string    $new_time    当前调用时字典树的更新时间
     * @return   null
     */
    static public function getRecTrie($tree_file, $new_time)
    {
        if(is_null(self::$_mtime))
        {
            self::$_mtime = $new_time;
        }

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

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

        return self::$_resTrie;

    }



    /**
     * 在源字符串中提取过滤出的敏感词
     *
     * @param     string     $str    源字符串
     * @param     array     $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,对外提交过滤接口访问

/**
 * 对外提供过滤HTTP访问接口.
 * Date: 2018/11/7
 * Time: 9:59
 */


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

// 设置时区
date_default_timezone_set('PRC');

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

// http服务绑定的ip及端口
$serv = new \swoole_http_server("127.0.0.1", 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();
添加新评论