大家好,我是老码,今天咱们来聊聊 WordPress 评论这事儿,特别是那个藏在幕后的英雄——wp_ajax_send_comment()
。 准备好了吗?咱们开讲!
一、 评论,WordPress的心脏跳动
评论,对于一个博客或者网站来说,简直就是心脏跳动。没有评论,就像一场独角戏,冷冷清清,毫无生气。 WordPress 当然深知这一点,所以它的评论系统相当完善,但也因此代码量也比较可观。
今天,我们聚焦在评论提交的 AJAX 请求处理上。 AJAX 意味着异步,这意味着用户提交评论后,无需刷新页面,就能看到评论提交的结果,大大提升了用户体验。而 wp_ajax_send_comment()
就是负责处理这个异步请求的关键函数。
二、 wp_ajax_send_comment()
在哪?
这个函数定义在 wp-includes/comment.php
文件里。 找到它,你就能发现宝藏。
三、 wp_ajax_send_comment()
的真面目
wp_ajax_send_comment()
并没有直接定义,而是通过 action hook 注册的。
add_action( 'wp_ajax_nopriv_wp_comment_post', 'wp_ajax_send_comment' ); // 未登录用户
add_action( 'wp_ajax_wp_comment_post', 'wp_ajax_send_comment' ); // 登录用户
这意味着,当用户提交评论时,WordPress 会触发 wp_comment_post
这个 action,然后 wp_ajax_send_comment
函数就会被调用。 注意区分 wp_comment_post
这个 action 和 wp_ajax_post
这个action。 wp_ajax_post
是处理普通 post 请求的,和评论没关系。
四、 源码剖析,一层层扒开它的外衣
好了,重头戏来了,咱们一步步剖析 wp_ajax_send_comment()
的源码。
function wp_ajax_send_comment() {
global $wp_query, $comment;
// Check nonce security.
check_ajax_referer( 'wp_comment_nonce', '_wpnonce' );
$comment = wp_handle_comment_submission( wp_unslash( $_POST ) );
if ( is_wp_error( $comment ) ) {
$data = array(
'error' => $comment->get_error_message(),
'success' => false,
);
wp_send_json( $data );
}
$user = wp_get_current_user();
do_action( 'set_comment_cookies', $comment, $user );
$GLOBALS['comment'] = $comment; // WPCS: override ok.
get_template_part( 'template-parts/comment', 'item' );
wp_die();
}
是不是很简单? 别急,咱们来细细分析:
-
全局变量:
global $wp_query, $comment;
声明了全局变量$wp_query
和$comment
。$comment
之后会被赋值为新提交的评论对象。
-
安全检查:
check_ajax_referer( 'wp_comment_nonce', '_wpnonce' );
这个是安全卫士,检查 nonce 值,防止 CSRF 攻击。wp_comment_nonce
是 action 的名称,_wpnonce
是前端传递 nonce 值的字段名。 如果 nonce 值不匹配,请求会被拒绝。 如何生成这个 nonce 值呢? 一般在评论表单中添加:wp_nonce_field( 'wp_comment_nonce', '_wpnonce' );
-
处理评论提交:
$comment = wp_handle_comment_submission( wp_unslash( $_POST ) );
这是核心部分,调用wp_handle_comment_submission
函数来处理评论提交。 这个函数会进行各种验证、过滤、保存等操作。wp_unslash( $_POST )
的作用是移除$_POST
数组中每个元素的反斜杠(如果存在)。 这是为了处理 magic quotes 的遗留问题。
-
错误处理:
if ( is_wp_error( $comment ) ) { ... }
如果wp_handle_comment_submission
函数返回一个 WP_Error 对象,说明评论提交失败。 此时,会构建一个包含错误信息的 JSON 对象,并发送给客户端。
-
设置 Cookie:
$user = wp_get_current_user();
获取当前用户对象。do_action( 'set_comment_cookies', $comment, $user );
触发set_comment_cookies
action,用于设置评论相关的 Cookie (例如,评论者的姓名、邮箱等)。
-
渲染评论:
$GLOBALS['comment'] = $comment;
将$comment
赋值给全局变量$GLOBALS['comment']
。 这是为了让模板文件能够访问到评论数据。get_template_part( 'template-parts/comment', 'item' );
加载template-parts/comment-item.php
模板文件,用于渲染新提交的评论。 这个模板文件负责将评论数据转换为 HTML 代码。 默认主题一般会有这个文件,如果没有,可以自行创建。
-
结束请求:
wp_die();
结束 AJAX 请求。 这个函数会输出0
并退出 PHP 脚本。
五、 wp_handle_comment_submission()
:评论处理的大管家
刚才我们提到, wp_handle_comment_submission()
是处理评论提交的核心函数。 这个函数的功能非常强大,我们来简单了解一下。
wp_handle_comment_submission()
主要做了以下事情:
- 获取评论数据: 从
$_POST
数组中获取评论数据,包括作者、邮箱、网址、评论内容等。 - 验证评论数据: 验证评论数据是否合法,例如,评论内容是否为空,邮箱格式是否正确等。
- 检查是否重复评论: 检查是否已经存在相同的评论。
- 检查是否被列入黑名单: 检查评论者 IP 地址、邮箱、网址等是否被列入黑名单。
- 检查是否需要审核: 根据 WordPress 的设置,判断评论是否需要人工审核。
- 保存评论: 将评论数据保存到数据库中。
- 发送通知邮件: 如果有新的评论需要审核,会发送通知邮件给管理员。
可以看出, wp_handle_comment_submission()
承担了评论处理的绝大部分工作。
六、 前端如何配合?
光有后端代码是不够的,前端也需要配合才能完成 AJAX 评论提交。 前端的主要任务是:
- 收集评论数据: 从评论表单中收集评论数据,例如,作者、邮箱、网址、评论内容等。
- 生成 nonce 值: 通过 WordPress 提供的函数生成 nonce 值,并将其添加到评论表单中。
- 发送 AJAX 请求: 使用 JavaScript 发送 AJAX 请求到
wp-admin/admin-ajax.php
。 - 处理响应: 根据 AJAX 请求的响应,显示评论提交的结果。
下面是一个简单的 JavaScript 代码示例:
jQuery(document).ready(function($) {
$('#commentform').submit(function(e) {
e.preventDefault(); // 阻止默认的表单提交
var data = $(this).serialize(); // 序列化表单数据
data += '&action=wp_comment_post'; // 添加 action 参数
$.ajax({
url: wp.ajax.settings.url, // WordPress AJAX URL
type: 'POST',
data: data,
dataType: 'json',
success: function(response) {
if (response.success === false) {
// 显示错误信息
alert(response.error);
} else {
// 显示评论
$('#comments').append(response); //这里要根据实际返回的评论HTML结构进行调整
$('#commentform')[0].reset(); // 清空表单
}
},
error: function(xhr, status, error) {
console.error('AJAX 请求失败: ' + error);
}
});
});
});
注意:
wp.ajax.settings.url
是 WordPress 提供的 AJAX URL,可以在前端通过wp_localize_script
函数传递。action=wp_comment_post
是告诉 WordPress 我们要执行wp_ajax_send_comment
函数。dataType: 'json'
指定服务器返回的数据类型为 JSON。- 成功提交之后如何显示评论,需要根据你的主题模板进行调整。 默认情况下,
get_template_part( 'template-parts/comment', 'item' );
会加载评论模板,然后你需要将这个模板返回的 HTML 代码插入到评论列表中。
七、 一些需要注意的点
- 评论审核: 如果评论需要审核,
wp_ajax_send_comment()
不会立即显示评论,而是会显示一条提示信息,告诉用户评论正在等待审核。 - 缓存: 如果你的网站使用了缓存,需要注意清除评论相关的缓存,否则新提交的评论可能不会立即显示。
- 主题兼容性: 不同的主题可能对评论的显示方式有不同的处理,因此你需要根据你的主题进行相应的调整。
- 插件冲突: 某些插件可能会修改评论的处理流程,导致
wp_ajax_send_comment()
无法正常工作。 如果遇到问题,可以尝试禁用插件来排除冲突。 - 垃圾评论: 垃圾评论是 WordPress 的一大难题。 可以使用 Akismet 等插件来过滤垃圾评论。
八、 实战演练:自定义评论 AJAX 处理
有时候,你可能需要自定义评论 AJAX 处理的流程。 例如,你可能需要在评论提交后发送自定义的通知邮件,或者需要在评论保存到数据库之前进行一些额外的处理。
要实现自定义的评论 AJAX 处理,你可以使用 wp_ajax_wp_comment_post
和 wp_ajax_nopriv_wp_comment_post
这两个 action hook。
下面是一个简单的示例:
function my_custom_comment_ajax_handler() {
// 1. 安全检查
check_ajax_referer( 'wp_comment_nonce', '_wpnonce' );
// 2. 处理评论提交 (可以修改 $_POST 数据)
$comment = wp_handle_comment_submission( wp_unslash( $_POST ) );
if ( is_wp_error( $comment ) ) {
$data = array(
'error' => $comment->get_error_message(),
'success' => false,
);
wp_send_json( $data );
}
// 3. 自定义操作
// 例如,发送自定义的通知邮件
$comment_id = $comment->comment_ID;
$comment_author_email = $comment->comment_author_email;
$comment_content = $comment->comment_content;
// 这里添加发送邮件的代码
// 例如: wp_mail( '[email protected]', 'New Comment', 'Author: ' . $comment_author_email . "n" . 'Content: ' . $comment_content );
// 4. 设置 Cookie
$user = wp_get_current_user();
do_action( 'set_comment_cookies', $comment, $user );
// 5. 渲染评论
$GLOBALS['comment'] = $comment; // WPCS: override ok.
ob_start();
get_template_part( 'template-parts/comment', 'item' );
$comment_html = ob_get_clean();
$data = array(
'success' => true,
'html' => $comment_html,
);
wp_send_json( $data );
// 6. 结束请求
wp_die();
}
remove_action( 'wp_ajax_nopriv_wp_comment_post', 'wp_ajax_send_comment' );
remove_action( 'wp_ajax_wp_comment_post', 'wp_ajax_send_comment' );
add_action( 'wp_ajax_nopriv_wp_comment_post', 'my_custom_comment_ajax_handler' );
add_action( 'wp_ajax_wp_comment_post', 'my_custom_comment_ajax_handler' );
在这个示例中,我们首先移除了默认的 wp_ajax_send_comment
函数,然后添加了自己的 my_custom_comment_ajax_handler
函数。 在 my_custom_comment_ajax_handler
函数中,我们可以执行任何自定义的操作。需要注意的是,我们要自己渲染评论,并且将渲染的HTML代码通过json返回给前端。
九、 总结
wp_ajax_send_comment()
是 WordPress 评论 AJAX 处理的核心函数。 通过深入了解它的源码,我们可以更好地理解 WordPress 评论系统的运作机制,并可以根据自己的需求进行自定义。
希望今天的讲座对你有所帮助。 记住,编程的世界充满了乐趣,只要你肯学习,就能掌握它。 下次再见!