文本检测(words-match)

感谢Easyswoole开发组的其它小伙伴的耐心指导和AbelZhou开源的字典树供我学习

words-match组件是基于字典树(DFA)并利用UnixSock通讯和自定义进程实现,开发本组件的目的是帮小伙伴们快速部署敏感词检测服务,这对于内容型产品来说非常重要。

::: warning 此组件稳定后,会尝试使用AC自动机或其它检测方式,提供底层可配置化检测服务 :::

使用场景

博客:评论、文章

即时通讯: 聊天室中的消息

只要和文本内容相关的都有应用场景

安装

  1. composer require easyswoole/words-match

准备词库

服务启动的时候会一行一行将数据读出来,每一行的第一列为敏感词,其它列为附属信息

  1. php,是世界上,最好的语言
  2. java
  3. golang
  4. 程序员
  5. 代码
  6. 逻辑

::: warning 注意!!!!!! 服务启动时可以用setDefaultWordBank 方法指定默认加载的词库。 :::

代码示例

  1. <?php
  2. namespace EasySwoole\EasySwoole;
  3. use EasySwoole\EasySwoole\Swoole\EventRegister;
  4. use EasySwoole\EasySwoole\AbstractInterface\Event;
  5. use EasySwoole\Http\Request;
  6. use EasySwoole\Http\Response;
  7. use EasySwoole\WordsMatch\WordsMatchClient;
  8. use EasySwoole\WordsMatch\WordsMatchServer;
  9. class EasySwooleEvent implements Event
  10. {
  11. public static function initialize()
  12. {
  13. // TODO: Implement initialize() method.
  14. date_default_timezone_set('Asia/Shanghai');
  15. }
  16. public static function mainServerCreate(EventRegister $register)
  17. {
  18. // TODO: Implement mainServerCreate() method.
  19. WordsMatchServer::getInstance()
  20. ->setMaxMem('1024M') // 每个进程最大内存
  21. ->setProcessNum(5) // 设置进程数量
  22. ->setServerName('Easyswoole words-match')// 服务名称
  23. ->setTempDir(EASYSWOOLE_TEMP_DIR)// temp地址
  24. ->setWordsMatchPath(EASYSWOOLE_ROOT.'/WordsMatch/')
  25. ->setDefaultWordBank('comment.txt')// 服务启动时默认导入的词库文件路径
  26. ->setSeparator(',')// 词和其它信息分隔符
  27. ->attachToServer(ServerManager::getInstance()->getSwooleServer());
  28. }
  29. public static function onRequest(Request $request, Response $response): bool
  30. {
  31. // TODO: Implement onRequest() method.
  32. $res = WordsMatchClient::getInstance()->search('php是世界上最好的语言,其它类型的程序员不认可php的这句话,比如java、golang。');
  33. var_dump($res);
  34. return true;
  35. }
  36. public static function afterRequest(Request $request, Response $response): void
  37. {
  38. // TODO: Implement afterAction() method.
  39. }
  40. }

命中结果

  1. array(4) {
  2. ["e1bfd762321e409cee4ac0b6e841963c"]=>
  3. array(3) {
  4. ["word"]=>
  5. string(3) "php"
  6. ["other"]=>
  7. array(2) {
  8. [0]=>
  9. string(12) "是世界上"
  10. [1]=>
  11. string(15) "最好的语言"
  12. }
  13. ["count"]=>
  14. int(2)
  15. }
  16. ["72d9adf4944f23e5efde37f6364c126f"]=>
  17. array(3) {
  18. ["word"]=>
  19. string(9) "程序员"
  20. ["other"]=>
  21. array(0) {
  22. }
  23. ["count"]=>
  24. int(1)
  25. }
  26. ["93f725a07423fe1c889f448b33d21f46"]=>
  27. array(3) {
  28. ["word"]=>
  29. string(4) "java"
  30. ["other"]=>
  31. array(0) {
  32. }
  33. ["count"]=>
  34. int(1)
  35. }
  36. ["21cc28409729565fc1a4d2dd92db269f"]=>
  37. array(3) {
  38. ["word"]=>
  39. string(6) "golang"
  40. ["other"]=>
  41. array(0) {
  42. }
  43. ["count"]=>
  44. int(1)
  45. }
  46. }

::: warning word:命中的敏感词,other:为其它信息,count:此敏感词在内容中命中的次数 :::

支持的方法

WordsMatchServer

设置临时目录

  1. public function setTempDir(string $tempDir): WordsMatchServer

设置进程数量,默认3

  1. public function setProcessNum(int $num): WordsMatchServer

设置每个进程最多所占内存大小

  1. public function setMaxMem(string $maxMem='512M')

设置UnixSocket的Backlog队列长度

  1. public function setBacklog(?int $backlog = null)

设置服务名称

  1. public function setServerName(string $serverName): WordsMatchServer

服务启动时默认加载的词库

  1. public function setDefaultWordBank(string $defaultWordBank): WordsMatchServer

绑定到当前主服务

  1. function attachToServer(swoole_server $server)

敏感词和其它信息的分隔符

  1. public function setSeparator(string $separator): WordsMatchServer

组件根路径

  1. public function setWordsMatchPath(string $path): WordsMatchServer

WordsMatchClient

添加敏感词

  1. public function append($word, array $otherInfo=[], float $timeout = 1.0)

移除敏感词

  1. public function remove($word, float $timeout = 1.0)

检测内容

第二个参数默认无过滤,如果下面三种方式满足不了需求,可自行过滤。

Package::FILTER_CEN(只保留中文、英文、数字)

Package::FILTER_C(只保留中文)

Package::FILTER_EMOJI(过滤掉表情)

  1. public function search(string $word, int $type, float $timeout=1.0);

导入词库,此方法可以将新词库追加到正在运行的字典树中也可以覆盖字典树,这样就可以做到实时的词库切换

  1. public function import($fileName, $separator=',', $isCover=false, float $timeout=1.0)

导出词库,此方法可以将字典树正在运行中的敏感词落地到文件中

  1. public function export($fileName, $separator=',', float $timeout=1.0)