本文约 3,450 字,预计阅读 9 分钟。文中命令与配置均经过实测,可直接参考执行。
引言:一个不该被低估的攻击面
很多人觉得评论功能无所谓,开着就行。但真实情况是:
- 一个没防护的 WordPress 站,开放评论后通常 48 小时内开始收到垃圾评论,一周后能到每天几百条;
- 每条垃圾评论都往
wp_comments和wp_commentmeta插行,一年下来几万条,文章页查询评论变慢,数据库从 20MB 涨到 300MB; - 垃圾评论里带的外链,是搜索引擎判定你站点”链接农场”的直接证据,会拉低整站权重;
- 评论区的
author字段如果不转义,是 XSS 和 SQL 注入的老牌入口。
所以讨论设置不是”锦上添花”,是站点运维的必要一环。
原理分析:评论的三个存储位与两道开关
评论数据存在 wp_comments 表,comment_approved 字段有三个值:1(已批准)、0(待审)、spam(垃圾)。所有”未读/待审”都是 0。
开关分两层,容易搞混:
- 全局默认(设置 → 讨论 → 默认文章设置):控制新发布文章的默认评论状态。
- 单篇文章覆盖(文章编辑页右上角”讨论”面板,或快速编辑):每篇文章可以单独覆盖全局设置。
关键坑点:改全局设置不会影响已发布的文章。很多人关了评论,发现旧文章评论框还在,就是这个原因。
另外还有第三个隐藏开关:comment_status 字段在数据库里是 open / closed,批量关要改这个字段:
UPDATE wp_posts SET comment_status = 'closed'
WHERE post_type = 'post' AND post_status = 'publish';
保姆级实操
场景一:彻底关闭全站评论
三个地方一起做:
- 设置 → 讨论 → 取消”允许他人在新文章上发表评论”(同时取消”发送 trackback”);
- 批量关掉存量文章:
bash
wp post list --post_type=post --format=ids | xargs -I{} wp post update {} --comment_status=closed
或者更快:
sql
UPDATE wp_posts SET comment_status='closed', ping_status='closed'
WHERE post_status='publish';
- 如果主题硬编码输出评论框(没用
comments_open()判断),去改主题模板,或装 “Disable Comments” 插件全局关。
场景二:只保留登录用户评论
设置 → 讨论 → 勾选”用户必须注册并登录才可以发表评论”。这一条能挡掉 95% 的机器垃圾,代价是普通访客评论门槛变高。企业站、技术博客用这个方案很合适。
场景三:保留开放评论但上四道防线
防线 1:人工首审
设置 → 讨论 → 勾选”评论必须经人工批准”;再勾”评论者先前须有已通过的评论”——这样同一个人第二次评论就自动放行,兼顾体验。
防线 2:黑名单过滤
设置 → 讨论 → 评论审核 / 评论黑名单 两个框:
- 评论审核:命中关键词的评论进入待审队列(不清空);
- 评论黑名单:命中关键词的评论直接标记为垃圾。
常用的黑名单词(针对中文站):
http://
https://
[url]
<a href
casino
viagra
cialis
贷款
博彩
刷单
免费下载
注意:http:// 这类词要谨慎,会误伤正常带链接的评论。建议只加明确的垃圾词。
防线 3:Akismet
WordPress 自带的 Akismet 插件,去 akismet.com 申请 API Key(个人站免费,商业站收费)。它靠全网共享的垃圾特征库判断,准确率很高。
配好后检查:
wp plugin status akismet
后台 插件 → Akismet → 设置,把”自动丢弃最严重的垃圾评论”勾上,避免垃圾数据入库。
防线 4:验证码
装 Simple Cloudflare Turnstile,勾选评论表单。这是唯一能挡住”真人刷评论”的手段。
场景四:清理已堆积的垃圾评论
# 先看有多少
wp comment list --status=spam --format=count
wp comment list --status=0 --format=count
# 删除垃圾评论
wp comment delete $(wp comment list --status=spam --format=ids) --force
# 直接 SQL(更快,先备份)
DELETE c, cm
FROM wp_comments c
LEFT JOIN wp_commentmeta cm ON cm.comment_id = c.comment_ID
WHERE c.comment_approved = 'spam';
OPTIMIZE TABLE wp_comments;
场景五:评论分页与性能优化
评论多的文章页会很慢。设置 → 讨论:
- 勾选”分页显示评论”,每页 20 条,
last页作为默认显示; - 关闭”显示头像”(头像走 gravatar.com,国内加载极慢甚至超时,是前台慢的常见元凶)。
如果必须显示头像,装 “WP User Avatar” 让用户上传本地头像,或替换 gravatar 源:
add_filter( 'get_avatar_url', function( $url ) {
return str_replace(
array( 'www.gravatar.com', '0.gravatar.com', '1.gravatar.com', '2.gravatar.com', 'secure.gravatar.com' ),
'cravatar.cn',
$url
);
});
cravatar.cn 是国内可用的 gravatar 镜像。
场景六:关闭通知轰炸
设置 → 讨论 → 取消”有人发表评论时通知我”和”评论需要版主审核时通知我”。评论量大时这两项会疯狂发邮件,甚至触发邮件服务商限流。
常见踩坑与失败案例
- 案例一:关了讨论设置的评论开关,前台评论框还在。原因是主题
comments.php里直接写了表单,没包if ( comments_open() )。要么改主题,要么用插件全局拦截。 - 案例二:批量关评论用了 SQL,但忘了改
ping_status,结果 trackback 垃圾照收。两个字段一起改。 - Akismet 突然全部判为垃圾:站点 API Key 过期或超出配额(商业站免费 Key 会被限制)。去后台看 Akismet 的账户状态。
- 评论通知邮件发不出:SMTP 没配。装 WP Mail SMTP 配好再测。
- 评论分页后 SEO 问题:分页 URL 是
?cpage=2或用comment-page-2,会在 Google 里产生大量重复内容页。用 SEO 插件给comment-page-*加noindex。 - 嵌套评论层级过深:设置 → 讨论 → 勾选”启用嵌套评论”并设置层级为 3~5。不限制层级会出现十几层缩进,手机端完全没法看。
- WordPress 6.x 的评论区 XSS:老主题如果在
comments.php里直接echo $comment->comment_author,存在存储型 XSS。必须esc_html()。检查:
bash
grep -rn "comment_author" wp-content/themes/你的主题/comments.php
总结
评论治理的策略分三档:不需要互动 → 全站关(三个地方一起关);需要互动但怕垃圾 → 登录才能评 + 人工首审 + Akismet;开放评论 → 四道防线全上 + 头像换国内源 + 评论分页。存量垃圾评论用 wp comment delete 或双表 DELETE 清理后记得 OPTIMIZE TABLE。另外有一条额外收益:清理垃圾评论后,文章页的数据库查询压力会明显下降,对 WordPress 性能优化 也有帮助。
