本文目录导读:

在PHP API中实现垃圾过滤(Spam Filtering),通常针对(如评论、消息)或请求行为(如频繁提交),以下是几种常见实现方式:
基于关键词过滤
简单关键词匹配
function isSpamKeyword($text) {
$spamKeywords = [
'免费领取', '点击这里', '赚钱', 'VIP', '代购',
'彩票', '赌博', '色情', '刷单', '加微信'
];
foreach ($spamKeywords as $keyword) {
if (mb_stripos($text, $keyword) !== false) {
return true;
}
}
return false;
}
正则表达式模式匹配
function spamPatternDetect($text) {
$patterns = [
'/\b(https?:\/\/[^\s]+)\b/i', // URL链接
'/\d{11,}/', // 连续的手机号
'/(.)\1{5,}/', // 重复字符(如: "aaaaaa")
'/\b(免费|赚钱|点击)\b.*\b(领取|注册|投资)\b/i' // 组合关键词
];
foreach ($patterns as $pattern) {
if (preg_match($pattern, $text)) {
return true;
}
}
return false;
}
基于频率和行为分析
请求频率限制(Rate Limiting)
function checkRateLimit($userId, $action = 'submit', $limit = 10, $window = 3600) {
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$key = "rate_limit:{$action}:{$userId}";
$current = $redis->get($key);
if ($current !== false && $current >= $limit) {
return false; // 超过限制
}
// 增加计数并设置过期时间
$redis->incr($key);
if ($current === false) {
$redis->expire($key, $window);
}
return true;
}
时间间隔检测
function checkTimeInterval($userId) {
$lastSubmit = getLastSubmitTime($userId);
if ($lastSubmit && (time() - $lastSubmit) < 10) {
return true; // 小于10秒的快速提交视为垃圾
}
return false;
}
分析
贝叶斯过滤(简单实现)
class BayesianFilter {
private $spamWords = [];
private $hamWords = [];
private $spamCount = 0;
private $hamCount = 0;
public function train($text, $isSpam) {
$words = $this->tokenize($text);
if ($isSpam) {
foreach ($words as $word) {
$this->spamWords[$word] = ($this->spamWords[$word] ?? 0) + 1;
}
$this->spamCount++;
} else {
foreach ($words as $word) {
$this->hamWords[$word] = ($this->hamWords[$word] ?? 0) + 1;
}
$this->hamCount++;
}
}
public function classify($text) {
$words = $this->tokenize($text);
$spamProb = 1.0;
$hamProb = 1.0;
foreach ($words as $word) {
// 计算该词在垃圾和正常邮件中的概率
$spamWordProb = ($this->spamWords[$word] ?? 0) / max($this->spamCount, 1);
$hamWordProb = ($this->hamWords[$word] ?? 0) / max($this->hamCount, 1);
$spamProb *= $spamWordProb;
$hamProb *= $hamWordProb;
}
$totalProb = $spamProb + $hamProb;
return $totalProb > 0 ? $spamProb / $totalProb : 0.5;
}
private function tokenize($text) {
// 分词并过滤停用词
$words = preg_split('/\s+/', mb_strtolower($text));
return array_filter($words, function($word) {
return mb_strlen($word) > 2; // 过滤短词
});
}
}
完整API实现示例
class SpamFilter {
private $config;
public function __construct($config = []) {
$this->config = array_merge([
'keyword_filter' => true,
'pattern_filter' => true,
'frequency_filter' => true,
'time_filter' => true,
'min_interval' => 10, // 最小间隔(秒)
'max_frequency' => 10, // 最大提交次数
'frequency_window' => 3600 // 频率统计窗口(秒)
], $config);
}
public function filter($request) {
$userId = $request['user_id'] ?? 'anonymous';
$content = $request['content'] ?? '';
$ip = $request['ip'] ?? $_SERVER['REMOTE_ADDR'];
$reasons = [];
// 1. 关键词过滤
if ($this->config['keyword_filter'] && $this->keywordCheck($content)) {
$reasons[] = '包含垃圾关键词';
}
// 2. 正则模式匹配
if ($this->config['pattern_filter'] && $this->patternCheck($content)) {
$reasons[] = '匹配垃圾模式';
}
// 3. 频率检测
if ($this->config['frequency_filter'] && !$this->frequencyCheck($userId, $ip)) {
$reasons[] = '提交过于频繁';
}
// 4. 时间间隔检测
if ($this->config['time_filter'] && !$this->timeCheck($userId)) {
$reasons[] = '提交间隔过短';
}
if (!empty($reasons)) {
return [
'is_spam' => true,
'reasons' => $reasons,
'score' => count($reasons) / 4
];
}
return [
'is_spam' => false,
'score' => 0
];
}
private function keywordCheck($text) {
$keywords = ['免费', '赚钱', '点击', '领取', '彩票'];
foreach ($keywords as $keyword) {
if (mb_stripos($text, $keyword) !== false) {
return true;
}
}
return false;
}
private function patternCheck($text) {
$patterns = [
'/\bhttps?:\/\/[^\s]+\b/',
'/\d{11,}/',
'/(.)\1{6,}/'
];
foreach ($patterns as $pattern) {
if (preg_match($pattern, $text)) {
return true;
}
}
return false;
}
private function frequencyCheck($userId, $ip) {
// 使用Redis实现频率控制
return true; // 示例简化
}
private function timeCheck($userId) {
// 检查用户最后提交时间
return true; // 示例简化
}
}
// 使用示例
$filter = new SpamFilter([
'keyword_filter' => true,
'pattern_filter' => true,
'min_interval' => 5
]);
$request = [
'user_id' => 123,
'content' => '免费领取大奖,点击链接 http://spam.com',
'ip' => '192.168.1.1'
];
$result = $filter->filter($request);
// API返回
header('Content-Type: application/json');
if ($result['is_spam']) {
http_response_code(403);
echo json_encode([
'error' => '内容包含垃圾信息',
'spam_score' => $result['score'],
'reasons' => $result['reasons']
]);
} else {
echo json_encode(['success' => true]);
}
进阶:使用第三方服务
// 使用 Akismet 反垃圾服务
function akismetCheck($content, $author = '', $email = '') {
$apiKey = 'your_akismet_api_key';
$blogUrl = 'https://yourwebsite.com';
$data = [
'blog' => $blogUrl,
'user_ip' => $_SERVER['REMOTE_ADDR'],
'user_agent' => $_SERVER['HTTP_USER_AGENT'],
'comment_author' => $author,
'comment_author_email' => $email,
'comment_content' => $content
];
$ch = curl_init("https://{$apiKey}.rest.akismet.com/1.1/comment-check");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
return trim($response) === 'true';
}
建议的实践方案
- 多维度检测:结合多种方法,提高准确率
- 白名单机制:对VIP用户降低检查频率
- 机器学习模型:使用PHP-ML或调用外部AI服务
- 分级处理:高概率垃圾直接拒绝,中等概率暂存审核
- 记录日志:记录被过滤的内容,用于优化算法
- 定期更新:定期更新关键词库和模式库
建议初期使用关键词+正则+频率限制的组合方案,后期根据实际需求引入机器学习模型。