PHP项目怎样实现内容审核通过?

wen PHP项目 66

本文目录导读:

PHP项目怎样实现内容审核通过?

  1. 方案一:状态字段 + 人工审核
  2. 方案二:结合 AI 自动审核(敏感词 + 文本识别)
  3. 方案三:队列 + 异步审核
  4. 总结与建议

在 PHP 项目中实现内容审核功能,通常需要一个完整的流程,包括用户提交审核人/系统审核状态更新前台展示

以下是几种主流的实现方案和核心代码逻辑:

状态字段 + 人工审核

这是最常见、最可控的方式,在数据表中增加一个status字段,通过后台管理员手动审核。

数据库设计

在需要审核的表中(如 articles, comments, posts)添加字段:

ALTER TABLE articles ADD COLUMN `status` TINYINT NOT NULL DEFAULT 0 COMMENT '状态: 0=待审核, 1=审核通过, 2=审核不通过';
ALTER TABLE articles ADD COLUMN `reviewer_id` INT DEFAULT NULL COMMENT '审核人ID';
ALTER TABLE articles ADD COLUMN `review_time` DATETIME DEFAULT NULL COMMENT '审核时间';
ALTER TABLE articles ADD COLUMN `review_reason` VARCHAR(500) DEFAULT NULL COMMENT '审核不通过原因';

用户提交代码

时,Status 默认设置为 0(待审核)。

// user_submit.php
<?php
// 假设已经获取了表单数据
$title = $_POST['title'];
$content = $_POST['content'];
// 插入数据库,状态默认待审核
$sql = "INSERT INTO articles (title, content, user_id, status, created_at) VALUES (?, ?, ?, 0, NOW())";
$stmt = $pdo->prepare($sql);
$stmt->execute([$title, $content, $userId]);
echo "发布成功,请等待管理员审核。";

后台审核代码

管理员在后台进行审核操作,更新状态。

// admin_review.php
<?php
// 获取待审核的文章列表
$sql = "SELECT * FROM articles WHERE status = 0 ORDER BY created_at DESC";
$pendingArticles = $pdo->query($sql)->fetchAll();
// 处理审核操作
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $articleId = $_POST['article_id'];
    $action = $_POST['action']; // 'approve' 或 'reject'
    $reason = $_POST['reason'] ?? null;
    $newStatus = ($action === 'approve') ? 1 : 2;
    $sql = "UPDATE articles SET status = ?, reviewer_id = ?, review_time = NOW(), review_reason = ? WHERE id = ?";
    $stmt = $pdo->prepare($sql);
    $stmt->execute([$newStatus, $adminId, $reason, $articleId]);
    // 可以发送通知给用户(邮件、站内信等)
    echo "审核完成。";
}

前台展示代码

前端只查询或显示状态为“审核通过”的内容。

// index.php
<?php
// 只获取审核通过的文章
$sql = "SELECT * FROM articles WHERE status = 1 ORDER BY created_at DESC LIMIT 20";
$articles = $pdo->query($sql)->fetchAll();

结合 AI 自动审核(敏感词 + 文本识别)

如果用户量很大,人工忙不过来,可以先让机器过滤一遍。

敏感词过滤

使用 DFA(确定性有限自动机)算法进行敏感词检测。

// SensitiveFilter.php
class SensitiveFilter {
    private $dict = [];
    public function loadWords(array $words) {
        foreach ($words as $word) {
            $this->addWord($word);
        }
    }
    private function addWord($word) {
        $len = mb_strlen($word);
        $node = &$this->dict;
        for ($i = 0; $i < $len; $i++) {
            $char = mb_substr($word, $i, 1);
            if (!isset($node[$char])) {
                $node[$char] = [];
            }
            $node = &$node[$char];
        }
        $node['end'] = true; // 标记为敏感词结尾
    }
    public function hasSensitive($text) {
        $len = mb_strlen($text);
        for ($i = 0; $i < $len; $i++) {
            $node = &$this->dict;
            $j = $i;
            while ($j < $len) {
                $char = mb_substr($text, $j, 1);
                if (isset($node[$char])) {
                    $node = &$node[$char];
                    if (isset($node['end'])) {
                        return true; // 发现敏感词
                    }
                    $j++;
                } else {
                    break;
                }
            }
        }
        return false;
    }
}
// 使用
$filter = new SensitiveFilter();
$filter->loadWords(['暴力', '色情']);
if ($filter->hasSensitive($content)) {
    // 自动标记为待人工审核或退回
    echo "内容包含敏感词,需要审核。";
    $status = 2; // 或保持0
}

调用第三方内容安全 API

使用云服务(百度AI、阿里云、腾讯云等)的文本/图片审核接口。

// 使用阿里云内容安全(示例)
use AlibabaCloud\Client\AlibabaCloud;
function checkContent($text) {
    AlibabaCloud::accessKeyClient('your-access-key', 'your-access-secret')
        ->regionId('cn-shanghai')
        ->asDefaultClient();
    $result = AlibabaCloud::rpc()
        ->product('Green')
        ->version('2017-12-21')
        ->action('TextScan')
        ->method('POST')
        ->options([
            'query' => [
                'RegionId' => 'cn-shanghai',
                'Content' => json_encode([
                    'tasks' => [['content' => $text]],
                    'scenes' => ['antispam']
                ]),
            ],
        ])
        ->request();
    $body = $result->toArray();
    // 解析结果:判断是否需要人工审核或拦截
    // ...
}

自动化工作流(推荐)

结合方案一和方案二,形成一个自动化 + 人工兜底的流程:

  1. 用户提交status = 0
  2. AI 预审
    • 通过:status = 1(直接发布)
    • 疑似违规(中等风险):status = 0(送入人工审核队列)
    • 明确违规(高风险):status = 2(自动退回,需通知用户申诉)
  3. 人工复审(对 AI 没法判断的内容进行最终确认)。

队列 + 异步审核

为了避免用户提交时等待 AI 审核结果,可以使用消息队列(RabbitMQ, Redis,或 PHP 的 pcntl_fork)。

  1. 用户提交后,直接将数据写入数据库(status = 0)。
  2. 将审核任务推送到队列(Redis List 或 RabbitMQ)。
  3. 后台消费者 Worker(一个常驻 PHP 脚本)从队列中取任务,调用 AI 接口或敏感词库审核。
  4. 审核完成后,Worker 更新数据库状态。
  5. (可选)通过 WebSocket 或轮询通知用户审核结果。

总结与建议

场景 推荐方案 说明
小型项目 / 用户少 方案一 纯人工审核,开发量小,可控。
中型项目 / 内容较多 方案一 + 敏感词预检 机器拦掉明显违规的,剩下人工审。
大型项目 / 海量 UGC 方案一 + AI 自动审核 + 异步队列 高并发、高过滤率、人工只审长尾。

核心步骤总结:

  1. 加状态字段 (status)
  2. 写审核逻辑 (用户提交流程、后台审核流程、前台展示过滤)
  3. 加安全检测 (敏感词 + 云 API)
  4. 加通知机制 (审核通过/驳回后,通知用户)

特别注意: 如果你的项目有 App 端或需要实时反馈审核状态,建议使用 WebSocketServer-Sent Events (SSE) 推送给用户,而不是让用户手动刷新页面。

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