本文目录导读:

我来介绍PHP项目中敏感词库的加载、更新和使用方案。
敏感词存储方案
文件存储(简单方案)
// sensitive_words.txt 敏感词1 敏感词2 敏感词3
数据库存储(推荐)
CREATE TABLE sensitive_words (
id INT PRIMARY KEY AUTO_INCREMENT,
word VARCHAR(100) NOT NULL,
level INT DEFAULT 1, -- 敏感级别
status TINYINT DEFAULT 1, -- 1启用 0禁用
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY uk_word (word)
);
敏感词加载类
<?php
class SensitiveWordFilter
{
private $wordTree = [];
private $lastUpdateTime = 0;
private $updateInterval = 300; // 5分钟检查更新
private $cacheKey = 'sensitive_words_tree';
private $useCache = false;
/**
* 构造函数
* @param bool $useCache 是否使用缓存
*/
public function __construct($useCache = false)
{
$this->useCache = $useCache;
$this->loadWords();
}
/**
* 加载敏感词
*/
public function loadWords()
{
if ($this->useCache) {
$this->loadFromCache();
} else {
$this->buildWordTree();
}
}
/**
* 从数据库构建词树
*/
private function buildWordTree()
{
// 从数据库加载
$words = $this->getWordsFromDB();
$this->wordTree = [];
foreach ($words as $word) {
$this->addWord($word);
}
$this->lastUpdateTime = time();
}
/**
* 添加单个词到树
*/
private function addWord($word)
{
$word = trim($word);
if (empty($word)) return;
$len = mb_strlen($word);
$tree = &$this->wordTree;
for ($i = 0; $i < $len; $i++) {
$char = mb_substr($word, $i, 1);
if (!isset($tree[$char])) {
$tree[$char] = [
'is_end' => false,
'children' => []
];
}
if ($i == $len - 1) {
$tree[$char]['is_end'] = true;
}
$tree = &$tree[$char]['children'];
}
}
/**
* 从数据库获取敏感词列表
*/
private function getWordsFromDB()
{
try {
$db = new PDO(
'mysql:host=localhost;dbname=your_db;charset=utf8mb4',
'username',
'password',
[
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
]
);
$stmt = $db->prepare('SELECT word FROM sensitive_words WHERE status = 1');
$stmt->execute();
return array_column($stmt->fetchAll(), 'word');
} catch (PDOException $e) {
error_log('Sensitive words load failed: ' . $e->getMessage());
return [];
}
}
/**
* 从缓存加载
*/
private function loadFromCache()
{
$cached = Cache::get($this->cacheKey);
if ($cached && !$this->isExpired()) {
$this->wordTree = $cached;
return;
}
$this->buildWordTree();
Cache::set($this->cacheKey, $this->wordTree, $this->updateInterval);
}
/**
* 检查是否过期
*/
private function isExpired()
{
return (time() - $this->lastUpdateTime) > $this->updateInterval;
}
/**
* 检查内容是否包含敏感词
*/
public function containsSensitiveWords($text)
{
return !empty($this->findSensitiveWords($text));
}
/**
* 查找所有敏感词
*/
public function findSensitiveWords($text)
{
$found = [];
$textLen = mb_strlen($text);
for ($i = 0; $i < $textLen; $i++) {
$tree = $this->wordTree;
$wordLen = 0;
for ($j = $i; $j < $textLen; $j++) {
$char = mb_substr($text, $j, 1);
if (!isset($tree[$char])) {
break;
}
$wordLen++;
if ($tree[$char]['is_end']) {
$found[] = mb_substr($text, $i, $wordLen);
}
$tree = $tree[$char]['children'];
}
}
return array_unique($found);
}
/**
* 替换敏感词
*/
public function replaceSensitiveWords($text, $replaceChar = '*')
{
$sensitiveWords = $this->findSensitiveWords($text);
foreach ($sensitiveWords as $word) {
$replacement = str_repeat($replaceChar, mb_strlen($word));
$text = str_replace($word, $replacement, $text);
}
return $text;
}
/**
* 强制更新词库
*/
public function forceUpdate()
{
$this->buildWordTree();
if ($this->useCache) {
Cache::set($this->cacheKey, $this->wordTree, $this->updateInterval);
}
}
}
词库更新方案
定时更新方案
<?php
class SensitiveWordsManager
{
private $db;
private $wordVersion = 'sensitive_words_version';
private $filter;
public function __construct($config)
{
$this->db = new PDO(...);
$this->filter = new SensitiveWordFilter(true);
}
/**
* 检查并更新词库
*/
public function checkUpdate()
{
$localVersion = $this->getLocalVersion();
$remoteVersion = $this->getRemoteVersion();
if ($remoteVersion > $localVersion) {
$this->updateLocal();
}
}
/**
* 获取本地版本号
*/
private function getLocalVersion()
{
return Cache::get($this->wordVersion, 0);
}
/**
* 获取远程版本号(可从API或文件获取)
*/
private function getRemoteVersion()
{
// 模拟从远程获取版本号
$apiUrl = 'https://api.example.com/sensitive-words/version';
$response = file_get_contents($apiUrl);
return json_decode($response, true)['version'];
}
/**
* 更新本地词库
*/
public function updateLocal()
{
$words = $this->fetchRemoteWords();
// 开启事务
$this->db->beginTransaction();
try {
// 清空旧数据
$this->db->exec('DELETE FROM sensitive_words');
// 插入新数据
$stmt = $this->db->prepare(
'INSERT INTO sensitive_words (word, level, status) VALUES (?, ?, 1)'
);
foreach ($words as $word) {
$stmt->execute([
$word['word'],
$word['level'] ?? 1
]);
}
$this->db->commit();
// 更新版本号
Cache::set($this->wordVersion, time());
// 强制更新过滤器
$this->filter->forceUpdate();
return true;
} catch (Exception $e) {
$this->db->rollBack();
error_log('Sensitive words update failed: ' . $e->getMessage());
return false;
}
}
/**
* 从远程获取敏感词
*/
private function fetchRemoteWords()
{
$apiUrl = 'https://api.example.com/sensitive-words/list';
$response = file_get_contents($apiUrl);
return json_decode($response, true)['data'];
}
}
使用示例
基础使用
// 初始化过滤器
$filter = new SensitiveWordFilter();
// 检查是否包含敏感词
$text = "这是一段包含敏感词的文本";
if ($filter->containsSensitiveWords($text)) {
echo "包含敏感词";
}
// 查找所有敏感词
$foundWords = $filter->findSensitiveWords($text);
print_r($foundWords);
// 替换敏感词
$cleanText = $filter->replaceSensitiveWords($text, '*');
echo $cleanText;
Web中间件使用
<?php
class SensitiveWordsMiddleware
{
private $filter;
public function __construct()
{
$this->filter = new SensitiveWordFilter(true);
}
public function handle($request, $next)
{
// 检查用户输入
$input = $request->all();
foreach ($input as $key => $value) {
if (is_string($value) && $this->filter->containsSensitiveWords($value)) {
return response()->json([
'code' => 400,
'message' => '输入包含敏感词汇'
], 400);
}
}
return $next($request);
}
}
定时更新脚本
<?php // update_sensitive_words.php require_once 'SensitiveWordFilter.php'; require_once 'SensitiveWordsManager.php'; // 定时任务示例(每5分钟执行一次) $manager = new SensitiveWordsManager($config); $manager->checkUpdate();
性能优化建议
<?php
/**
* 批量处理优化
*/
class OptimizedSensitiveWordFilter extends SensitiveWordFilter
{
/**
* 批量检查文本
*/
public function batchCheck(array $texts)
{
$results = [];
foreach ($texts as $key => $text) {
$results[$key] = [
'has_sensitive' => $this->containsSensitiveWords($text),
'clean_text' => $this->replaceSensitiveWords($text, '*')
];
}
return $results;
}
/**
* 使用文件缓存
*/
public function saveToFile($filePath)
{
file_put_contents(
$filePath,
serialize($this->wordTree)
);
}
public function loadFromFile($filePath)
{
if (file_exists($filePath)) {
$this->wordTree = unserialize(
file_get_contents($filePath)
);
}
}
}
这个方案提供了完整的敏感词库加载、更新和使用功能,支持:
- 高效的多词匹配算法
- 灵活的更新机制
- 缓存优化
- 批量处理
- 易于集成到现有项目
根据实际需求选择合适的存储和更新策略即可。