在逛博友的博客时,看到博友 @老狼 博文中提到的:他的博客评论发信,使用的是异步方式,即提交评论后,不会立刻触发SMTP发信,使用异步访问一个URL才发现,为省事就把这个URL交给DNSPOD的监控,每10分钟监控一次,等于每10分钟触发一次,有需要就发信。
顿时豁然开朗,之前飞牛在两年前就写过关于《WordPress评论的时候提交速度慢原因及解决办法》的相关探索,无奈知识有限,没有想到过异步方式。
WordPress 发表评论时,将通知邮件发送给管理员的操作。默认情况下,该操作同时执行。只有在邮件发送成功后,系统才能提示用户成功评论。在一些主机上,邮件发送相对较慢,导致用户等待时间较长。
飞牛的服务器在香港, 邮件服务器使用的QQ邮箱,导致用户登录或者评论文章都要等上一会。网上找了找教程,基本都是复制来复制去,尝试了很多方法都会报错有问题,最终经过不断的尝试,终于设置好了异步发送邮件,不阻塞用户当前操作,评论回复基本秒速,大家可以试一下。
一、配置好smtp邮件发送设置
默认情况下,WordPress使用不可靠的PHP邮件功能,并且所发出的电子邮件经常会被邮件服务商标记为垃圾邮件。使用SMTP服务器是确保WordPress电子邮件可传递性的最佳方法。
(一)使用插件:WP Mail SMTP。我用的是WP Mail SMTP 插件。
(二)使用代码:参考文章:《 WORDPRESS 代码实现SMTP发送邮件 评论+回复邮件通知》
二、修改邮件发送相关设置
安装好WP Mail SMTP插件后,设置相关邮件信息,测试是否能正常发送邮件。
修改WP Mail SMTP文件: wp-content/plugins/wp-mail-smtp/wp_mail_smtp.php
在里面添加下面的代码:
// 异步发送邮件的方法
function async_send_mail($comment_data) {
// 添加邮件内容的content-type为HTML
$headers = array(
'Content-Type: text/html; charset=UTF-8',
);
// 调用 wp_mail 函数以异步发送邮件,并包括头部信息
wp_mail($comment_data['to'], $comment_data['subject'], $comment_data['message'], $headers);
}
// 评论回复邮件通知
function comment_mail_notify_enqueue($comment_id) {
$admin_email = get_bloginfo('admin_email');
$comment = get_comment($comment_id);
$comment_author_email = trim($comment->comment_author_email);
$parent_id = $comment->comment_parent ? $comment->comment_parent : '';
$to = $parent_id ? trim(get_comment($parent_id)->comment_author_email) : '';
$spam_confirmed = $comment->comment_approved;
if (($parent_id != '') && ($spam_confirmed != 'spam') && ($to != $admin_email)) {
$comment_data = array(
'to' => $to,
'subject' => '您在 [' . get_option("blogname") . '] 的留言有了新回复',
'message' => '
这里添加邮件的内容。
' , // 添加您的邮件内容
);
// 异步发送邮件
wp_schedule_single_event(time() + 5, 'async_send_mail', array($comment_data));
}
}
add_action('comment_post', 'comment_mail_notify_enqueue');
// 异步发送邮件的定时任务
function async_send_mail_action($comment_data) {
async_send_mail($comment_data);
}
add_action('async_send_mail', 'async_send_mail_action');
// 异步邮件发送的代码
if (!defined('DOING_CRON') || !DOING_CRON) {
function wp_mail() {
$args = func_get_args();
$args[] = mt_rand();
wp_schedule_single_event(time() + 5, 'cron_send_mail', $args);
}
return;
}
function example_cron_send_mail() {
$args = func_get_args();
array_pop($args);
$endParam = end($args);
call_user_func_array('wp_mail', $args);
}
add_action('cron_send_mail', 'example_cron_send_mail', 10, 10);
PS:因为上述的代码设置之后,左侧的wp mail smtp邮件设置菜单会隐藏。如果要恢复菜单,只要去掉代码就好,不影响正常使用。
代码相关解释:
async_send_mail($comment_data)
函数:这是一个自定义函数,用于异步发送邮件。它接受一个关联数组$comment_data
作为参数,包括邮件收件人、主题和邮件内容。内部使用wp_mail
函数发送邮件,并指定邮件内容的 content-type 为 HTML。comment_mail_notify_enqueue($comment_id)
函数:这是一个 WordPress 动作钩子(action hook),当评论被发布时触发。它用于构建评论回复的邮件通知内容,并安排一个定时任务来异步发送邮件。具体功能包括:- 获取博客管理员的电子邮件地址。
- 获取新评论的详细信息,包括评论作者的电子邮件地址、父评论的 ID 以及评论是否被确认为垃圾评论。
- 如果是回复评论(有父评论),非垃圾评论,且评论接收者不是博客管理员,则构建邮件内容并将其包装在
$comment_data
数组中。 - 使用
wp_schedule_single_event
安排一个异步任务,在 5 秒后执行async_send_mail_action
函数,以异步发送邮件。
async_send_mail_action($comment_data)
函数:这是异步任务的回调函数,它将$comment_data
传递给async_send_mail
函数,以实际发送邮件。add_action
函数:用于将上述函数与 WordPress 动作钩子关联,以确保它们在适当的时机被执行。wp_mail()
函数:这是一个自定义的wp_mail
函数,用于触发定时任务cron_send_mail
,以异步发送邮件。它会在原始的wp_mail
函数中添加一个随机参数,并使用wp_schedule_single_event
安排一个cron_send_mail
任务,同时传递原始的参数列表。example_cron_send_mail()
函数:这是cron_send_mail
任务的回调函数,用于取出参数,并调用原始的wp_mail
函数以实际发送邮件。
三、一些注意事项
(一)确保您的 WordPress 网站已正确配置 “wp mail smtp” 插件,以便此代码能够正常工作。
(二)邮件内容的样式可以根据自己的来,或者看看这里《 wordpress 邮件内容美化》。
(三)目前网上搜索确实是找不到具体针对wordpress的教程,飞牛作为打字一指禅,也是慢慢摸索出来的,自己试了应该是有效果,我自己半吊子水平,不会系统地测试是否有效果。如果有大神有更好的办法,请及时留言教我,学习路上达者为先。
(四)暂时还没想到,不过一般情况下三点太少、五点太多,四点刚好。
PS重点:大家要用就直接拿去用,要是转载了在自己的网站还设置一堆的注册登录、回复隐藏可见,或者掐头去尾装原创,我是不能怎么样,不过你也就这样了。
参考:
https://wordpress.stackexchange.com/questions/185295/how-to-make-wordpress-emails-async
都是异步[微笑]
用redis队列应该会好一些的。
@林羽凡 安装过redis,可能是自己操作不对,会出错,发不出邮件。