PHP项目敏感词库如何加载更新使用

wen PHP项目 26

本文目录导读:

PHP项目敏感词库如何加载更新使用

  1. 敏感词存储方案
  2. 敏感词加载类
  3. 词库更新方案
  4. 使用示例
  5. 性能优化建议

我来介绍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)
            );
        }
    }
}

这个方案提供了完整的敏感词库加载、更新和使用功能,支持:

  • 高效的多词匹配算法
  • 灵活的更新机制
  • 缓存优化
  • 批量处理
  • 易于集成到现有项目

根据实际需求选择合适的存储和更新策略即可。

抱歉,评论功能暂时关闭!