WordPress注册激活邮件、密码修改邮件在QQ邮箱乱码无法打开的解决方法

最近发现WordPress的一个存在了很久的BUG,在一些WordPress站注册账号时,点击激活邮件的链接总是提示“您的密码重设链接无效,请在下方请求新链接”,把链接复制到浏览器地址栏中依然提示错误:

Wordpress注册激活邮件、密码修改邮件在QQ邮箱乱码无法打开的解决方法

这里主要有两个BUG,一是邮件URL中的“&”被解析成了“&amp;”,导致复制整条URL也会提示错误;另一个BUG是WordPress在URL添加了一个“<>”,其中的“>”会被一些邮件服务商(比如国内通用的QQ邮件)解析成URL的一部分,导致你的超链接由http://xxx.com变成了http://xxx.com>,这样肯定是打不开的。

Wordpress注册激活邮件、密码修改邮件在QQ邮箱乱码无法打开的解决方法

若是站点仅仅为内部人员开放注册,这些BUG倒也无关紧要,如果站点是开放注册,这样的用户体验显然太差,本来WordPress的注册流程就不太符合中国用户的使用习惯,再加上这种bug,你是想让用户骂娘吗?

解决方法也比较简单,方法一是直接去改系统文件 /wp-includes/pluggable.php,涉事代码约在1896行(不同WP版本行数可能稍有差异)也可以Ctrl+F下面的代码直接定位:

/* translators: %s: user login */
$message = sprintf(__('Username: %s'), $user-&gt;user_login) . "\r\n\r\n";
$message .= __('To set your password, visit the following address:') . "\r\n\r\n";
$message .= '&lt;' . network_site_url("wp-login.php?action=rp&amp;key=$key&amp;login=" . rawurlencode($user-&gt;user_login), 'login') . "&gt;\r\n\r\n";

把最后一行的“>”删掉,然后把“wp-login.php?action=rp&key=$key&login=“改成“wp-login.php?key=$key&action=rp&login=”就可以了,懂PHP的同学仔细看一下就能明白,都是一些字符串解析的小问题。

不过此方法会直接修改WP核心文件,我们可以自己写一个函数勾到相关的钩子上,把这些系统设置给覆盖掉,由于本人技术比较菜所以直接Google了一段代码如下:

// 函数+过滤器 修复wordpress注册邮件无法打开的BUG
// 参考https://wordpress.stackexchange.com/questions/296308/custom-welcome-email-wordpress
// 2018-9-19
function edit_user_notification_email( $wp_new_user_notification_email, $user, $user_email ) {
global $wpdb, $wp_hasher;
$key = wp_generate_password( 20, false );
/** This action is documented in wp-login.php */
do_action( 'retrieve_password_key', $user-&gt;user_login, $key );
// Now insert the key, hashed, into the DB.
if ( empty( $wp_hasher ) ) {
require_once ABSPATH . WPINC . '/class-phpass.php';
$wp_hasher = new PasswordHash( 8, true );
}
$hashed = time() . ':' . $wp_hasher-&gt;HashPassword( $key );
$wpdb-&gt;update( $wpdb-&gt;users, array( 'user_activation_key' =&gt; $hashed ), array( 'user_login' =&gt; $user-&gt;user_login ) );
$switched_locale = switch_to_locale( get_user_locale( $user ) );
// send message
$message .= sprintf('您正在%s注册新账号,您的用户名为:',get_bloginfo('name')) .$user-&gt;display_name. "\r\n\r\n";
$message .= '请点击下方链接设置您的密码:' . "\r\n\r\n";
$message .= network_site_url("wp-login.php?key=$key&amp;action=rp&amp;login=" . rawurlencode($user-&gt;user_login), 'login') . "\r\n\r\n\r\n";
$message .= '如果您在注册过程中遇到困难,请邮件联系 xxx@xxx.com' . "\r\n\r\n";
$wp_new_user_notification_email['message'] = $message;
return $wp_new_user_notification_email;
}
add_filter( 'wp_new_user_notification_email' , 'edit_user_notification_email', 10, 3 );

把这段代码添加到function.php即可解决,相关的邮件话术也可以自定义。

除此之外,当用户通过“忘记密码”找回密码时也会遭遇此BUG,相关解决方法可以参考WordPress大学的相关文章:https://www.wpdaxue.com/lost-password-error-invalidkey.html

5年前的文章了,WordPress官方一直没解决这个BUG,真是让人醉了。