PHP项目评论功能如何开发防灌水

wen PHP项目 28

本文目录导读:

PHP项目评论功能如何开发防灌水

  1. 前端基础限制(防小白/机器脚本)
  2. 后端核心防护(防绕过)
  3. 高级行为分析(防高级灌水)
  4. 内容可信度过滤
  5. 完整的服务端处理流程
  6. 推荐组合方案(根据项目规模)
  7. 重要提醒

开发PHP项目的评论防灌水功能,需要从前端限制后端验证行为分析内容过滤四个层面综合防范,以下是具体的技术方案和代码示例:

前端基础限制(防小白/机器脚本)

这些措施成本低,能过滤掉70%的初级攻击。

提交频率限制(JS侧)

<script>
let lastSubmitTime = 0;
const MIN_INTERVAL = 5000; // 5秒内只能提交一次
document.getElementById('commentForm').addEventListener('submit', function(e) {
    const now = Date.now();
    if (now - lastSubmitTime < MIN_INTERVAL) {
        e.preventDefault();
        alert('提交太快了,请稍候再试');
        return;
    }
    lastSubmitTime = now;
});
</script>

必填字段与格式校验

  • 验证邮箱格式、URL格式(如果允许)
  • 使用HTML5 required 属性,配合JS正则:
    function validateComment(content) {
      // 禁止纯数字、纯字母、重复字符
      if (/^(\d+)$/.test(content)) return false;
      if (/^(.)\1{5,}$/.test(content)) return false; // 如"哈哈哈哈哈哈"
      // 最小长度限制
      if (content.trim().length < 2) return false;
      return true;
    }

后端核心防护(防绕过)

后端是最终的防线,必须对所有输入进行严格检查。

频率限制(Rate Limiting)

基于IP+用户ID(如果登录)的滑动窗口限制:

<?php
class RateLimiter {
    private $redis;
    private $maxAttempts = 10;      // 最大次数
    private $windowTime = 3600;    // 窗口时间(秒)
    public function check($key) {
        $current = time();
        $windowStart = $current - $this->windowTime;
        // 使用Redis有序集合存储时间戳
        $this->redis->zRemRangeByScore($key, 0, $windowStart); // 清理过期记录
        $count = $this->redis->zCard($key);
        if ($count >= $this->maxAttempts) {
            return false; // 超过限制
        }
        $this->redis->zAdd($key, $current, $current . '_' . uniqid());
        $this->redis->expire($key, $this->windowTime);
        return true;
    }
}
// 使用
$limiter = new RateLimiter();
$ipKey = 'comment_limit:' . $_SERVER['REMOTE_ADDR'];
if (!$limiter->check($ipKey)) {
    die('评论过于频繁,请一小时后再试');
}
?>

验证码机制(CAPTCHA)

  • 简单验证:算术题(3+5=?)、简单图片
  • 高级验证:Google reCAPTCHA v3(无感验证)
  • 隐藏字段:使用Honeypot技术(对用户不可见,填了就是机器人):
    <!-- 对用户隐藏 -->
    <input type="text" name="website" style="display:none;" autocomplete="off">
后端检查 `$_POST['website']` 如果有值则拒绝。
#### 3. 内容安全过滤
```php
<?php
class CommentFilter {
    // 黑名单关键词
    private $badWords = ['http://', 'https://', '免费', '加微信', 'Q群'];
    // 链接检测
    public function hasLinks($content) {
        return preg_match('/https?:\/\/[^\s]+/i', $content);
    }
    // 重复内容检测(同一用户同样内容)
    public function isDuplicate($userId, $content) {
        global $db;
        $stmt = $db->prepare("SELECT COUNT(*) FROM comments 
                             WHERE user_id = ? AND content = ? 
                             AND created_at > DATE_SUB(NOW(), INTERVAL 1 DAY)");
        $stmt->execute([$userId, $content]);
        return $stmt->fetchColumn() > 0;
    }
    // 主要过滤逻辑
    public function sanitize($content) {
        // 1. 去除空白
        $content = trim($content);
        // 2. 检查长度
        if (mb_strlen($content) > 500) return false;
        // 3. 检查敏感词
        foreach ($this->badWords as $word) {
            if (stripos($content, $word) !== false) return false;
        }
        // 4. 检查链接(非白嫖网站)
        if ($this->hasLinks($content) && !$this->isWhitelistedDomain($content)) {
            return false;
        }
        return htmlspecialchars($content, ENT_QUOTES, 'UTF-8'); // XSS防护
    }
}
?>

高级行为分析(防高级灌水)

用户行为评分

根据以下维度给用户打分:

  • 新用户:注册<7天 → 限制评论数
  • 低质用户:之前评论被删除率>30% → 手动审核
  • 设备指纹:记录User-Agent、屏幕分辨率、时区(批量机器人往往一致)

时间模式检测

<?php
// 判断是否是机器人的时间规律
$submitTime = time();
if ($this->isBetween($submitTime, '00:00', '06:00')) {
    // 深夜提交,触发人工审核标记
    $this->markForReview($comment);
}
?>

文本模式分析

  • N-gram分析:检测重复短句(如"很好"重复10次)
  • 字符分布:检查字母/数字/中文的比例异常(如全英文+数字的垃圾评论)

内容可信度过滤

垃圾邮件检测

使用PHP的 akismet API 或 spamcheck 服务:

<?php
$akismet = new Akismet('your-api-key', 'https://yourdomain.com');
$akismet->setCommentAuthor($name);
$akismet->setCommentContent($content);
$akismet->setUserIP($_SERVER['REMOTE_ADDR']);
if ($akismet->isCommentSpam()) {
    // 标记为垃圾评论,不显示
    $comment->setStatus('spam');
}
?>

相似度检测重复发布(例如水军复制粘贴):

<?php
// 使用similar_text()检测
function isSimilarToRecent($content, $threshold = 80) {
    global $db;
    $stmt = $db->query("SELECT content FROM comments 
                       WHERE created_at > NOW() - INTERVAL 1 HOUR 
                       ORDER BY created_at DESC LIMIT 50");
    while ($row = $stmt->fetch()) {
        similar_text($content, $row['content'], $percent);
        if ($percent > $threshold) {
            return true;
        }
    }
    return false;
}
?>

完整的服务端处理流程

<?php
// 评论提交接口
public function submitComment($data) {
    $userId = $data['user_id'];
    $content = $data['content'];
    // 1. 频率检测
    if (!$this->rateLimitCheck($userId, $_SERVER['REMOTE_ADDR'])) {
        return ['success' => false, 'msg' => '操作过于频繁'];
    }
    // 2. Honeypot检测
    if (!empty($data['website'])) {
        return ['success' => false, 'msg' => '机器人检测失败'];
    }
    // 3. 验证码校验
    if (!$this->validateCaptcha($data['captcha'])) {
        return ['success' => false, 'msg' => '验证码错误'];
    }
    // 4. 内容过滤
    $filteredContent = $this->filter->sanitize($content);
    if ($filteredContent === false) {
        return ['success' => false, 'msg' => '评论内容含有违规信息'];
    }
    // 5. 重复检测
    if ($this->filter->isDuplicate($userId, $filteredContent)) {
        return ['success' => false, 'msg' => '请勿重复提交相同内容'];
    }
    // 6. 行为分析 - 判断是否标记审核
    $status = $this->behaviorAnalyzer->assess($userId);
    // 7. 存储到数据库(含审核状态)
    $this->saveComment($userId, $filteredContent, $status);
    return ['success' => true, 'msg' => '评论提交成功'];
}
?>

推荐组合方案(根据项目规模)

项目类型 必备措施 可选增强
小型个人博客 频率限制 + 简单验证码 + 内容过滤 Honeypot + 人工审核
中型社区 + reCAPTCHA v3 + 限频Redis + 文本模式 用户行为评分 + 黑白名单
大型网站 全部 + Akismet API + 机器学习判断 设备指纹 + 分布式限流

重要提醒

  1. 不要只依赖前端:所有前端验证都可以通过Curl等工具绕过
  2. 日志记录:记录所有被拒绝的请求(IP、时间、内容),便于后续调整策略
  3. 用户申诉:为被误判的用户提供申诉渠道(如“需要人工审核”)
  4. 逐步升级:先从最简单的频率限制+验证码做起,再根据灌水情况增加复杂度

通过以上组合策略,可以有效应对90%以上的灌水攻击,同时保持良好用户体验,如果需要更具体的代码实现(如自定义验证码、Redis限流示例),欢迎进一步沟通。

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