PHP实现非法词汇过滤的方法及代码是什么
Admin 2022-11-18 群英技术资讯 503 次浏览
这篇文章我们来了解“PHP实现非法词汇过滤的方法及代码是什么”的内容,小编通过实际的案例向大家展示了操作过程,简单易懂,有需要的朋友可以参考了解看看,那么接下来就跟随小编的思路来往下学习吧,希望对大家学习或工作能有帮助。
将关键词构造成一颗树,每个字都是一个节点。
遍历需要过滤的语句,将语句的每个字都去树中查找,看看是否存在。
构造一棵树简单,关键点是php
中遍历字符串需要自己正确的得到单个字符的长度。
简单遍历字符串的方法如下:
$strLen = mb_strlen($str);
for ($i = 0; $i < $strLen; $i++) {
echo mb_substr($str, $i, 1, "utf8"),PHP_EOL;
}
登录后复制
该方法是利用mb_*
系列函数来正确截取每个字符,处理大量字符串时速度非常慢,我猜测是:mb_substr
每截取一个字符,都要计算该字符串之前,有多少个字符。
正确的遍历字符串的方式是按utf8
的编码规律来截取字符串,具体请看下文。
<?php
/**
* 非法关键词检查
*/
class SensitiveWords
{
protected $tree = null;
protected $callIsNumeric = true;
/**
* 非法词汇列表,一个非法词汇占用一行
*/
public function __construct($path = __DIR__ . '/sensitiveWords.txt')
{
$this->tree = new WordNode();
$file = fopen($path, "r");
while (!feof($file)) {
$words = trim(fgets($file));
if ($words == '') {
continue;
}
//存在纯数字的非法词汇
if (is_numeric($words)) {
$this->callIsNumeric = false;
}
$this->setTree($words);
}
fclose($file);
}
protected function setTree($words)
{
$array = $this->strToArr($words);
$tree = $this->tree;
$l = count($array) - 1;
foreach ($array as $k => $item) {
$tree = $tree->getChildAlways($item);
if ($l == $k) {
$tree->end = true;
}
}
}
/**
* 返回包含的非法词汇
* @param string $str
* @return array
*/
public function check($str)
{
//先压缩字符串
$str = trim(str_replace([' ', "\n", "\r"], ['', '', ''], $str));
$ret = [];
loop:
$strLen = strlen($str);
if ($strLen === 0) {
return array_unique($ret);
}
//非法词汇中没有纯数字的非法词汇,待检测字符串又是纯数字的,则跳过不再检查
if ($this->callIsNumeric && is_numeric($str)) {
return array_unique($ret);
}
//挨个字符进行判断
$tree = $this->tree;
$words = '';
for ($i = 0; $i < $strLen; $i++) {
//unicode范围 --> ord 范围
//一字节 0-127 --> 0 - 127
//二字节 128-2047 --> 194 - 223
//三字节 2048-65535 --> 224 - 239
//四字节 65536-1114111 --> 240 - 244
//@see http://shouce.jb51.net/gopl-zh/ch3/ch3-05.html
$ord = ord($str[$i]);
if ($ord <= 127) {
$word = $str[$i];
} elseif ($ord <= 223) {
$word = $str[$i] . $str[$i + 1];
$i += 1;
} elseif ($ord <= 239) {
$word = $str[$i] . $str[$i + 1] . $str[$i + 2];
$i += 2;
} elseif ($ord <= 244) {
//四字节
$word = $str[$i] . $str[$i + 1] . $str[$i + 2] . $str[$i + 3];
$i += 3;
} else {
//五字节php都溢出了
//Parse error: Invalid UTF-8 codepoint escape sequence: Codepoint too large
continue;
}
//判断当前字符
$tree = $tree->getChild($word);
if (is_null($tree)) {
//当前字不存在,则截取后再次循环
$str = substr($str, $i + 1);
goto loop;
} else {
$words .= $word;
if ($tree->end) {
$ret[] = $words;
}
}
}
return array_unique($ret);
}
protected function strToArr($str)
{
$array = [];
$strLen = mb_strlen($str);
for ($i = 0; $i < $strLen; $i++) {
$array[] = mb_substr($str, $i, 1, "utf8");
}
return $array;
}
}
/**
* 单个字符的节点
*/
class WordNode
{
//是否为非法词汇末级节点
public $end = false;
//子节点
protected $child = [];
/**
* @param string $word
* @return WordNode
*/
public function getChildAlways($word)
{
if (!isset($this->child[$word])) {
$this->child[$word] = new self();
}
return $this->child[$word];
}
/**
* @param string $word
* @return WordNode|null
*/
public function getChild($word)
{
if ($word === '') {
return null;
}
if (isset($this->child[$word])) {
return $this->child[$word];
}
return null;
}
}
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
php中Phalcon框架需要学习以下内容:1、引入文件;2、安装命令行工具;3、运行命令;4、构造项目;5、生成控制器;
一些朋友遇到php安装扩展模块后,重启不生效的情况,这是什么原因呢?要怎么样解决?下面有php扩展安装步骤以及解决php扩展安装不生效的办法,供大家参考。
laravel框架怎样实现对敏感词汇过滤?在做开发的时候,有些需求需要对敏感词汇进行过滤,很多新手可能对此对如何实现这个功能不是很清楚,下面给大家分享一个对用户的签名,回复进行敏感词检测的实例,供大家参考学习。
本文实例讲述了PHP设计模式:适配器模式Adapter。分享给大家供大家参考,具体如下:
这篇文章主要介绍laravel数据库测试需要注意的事项,小编觉得比较实用,因此分享给大家作为参考,感兴趣的朋友可以参考一下,希望对大家学习有帮助,下面我们一起来了解一下。
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008