You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WordPress中wp_mail()发送单份邮件却重复接收问题

解决WordPress登录验证码邮件重复发送问题

核心问题分析

你当前的代码直接在全局作用域调用wp_mail(),如果这段代码所在的文件被WordPress多次加载(比如主题模板重复引入、插件钩子重复触发),或者用户多次点击登录按钮,就会导致重复发邮件。另外,没有任何请求去重或频率限制机制,是重复发送的关键原因。

解决方案步骤

1. 移除全局的wp_mail调用

删掉直接写在全局的var_dump(wp_mail(...)),改用WordPress的登录相关钩子触发邮件发送,避免无意义的重复执行。

2. 绑定到正确的登录触发钩子

绑定到authenticate钩子(用户登录验证阶段),同时添加防重复发送逻辑:用session记录最近一次发送邮件的时间,限制一定时间内只能发送一次。

3. 完整修正代码

<?php
// Config SMTP
define('SMTP_HOST', 'mail.x.ir');
define('SMTP_AUTH', true);
define('SMTP_PORT', '465');
define('SMTP_SECURE', 'ssl');
define('SMTP_USERNAME', 'tst@melad.ir');
define('SMTP_PASSWORD', 'x');
define('SMTP_FROM', 'x');
define('SMTP_FROMNAME', 'Developer');

add_action('phpmailer_init', 'send_smtp_email');
function send_smtp_email($phpmailer)
{
    $phpmailer->isSMTP();
    $phpmailer->Host       = SMTP_HOST;
    $phpmailer->SMTPAuth   = SMTP_AUTH;
    $phpmailer->Port       = SMTP_PORT;
    $phpmailer->SMTPSecure = SMTP_SECURE;
    $phpmailer->Username   = SMTP_USERNAME;
    $phpmailer->Password   = SMTP_PASSWORD;
    $phpmailer->From       = SMTP_FROM;
    $phpmailer->FromName   = SMTP_FROMNAME;
}

// 绑定登录验证钩子,发送验证码
add_filter('authenticate', 'send_login_verification_code', 10, 3);
function send_login_verification_code($user, $username, $password) {
    // 仅在用户存在且未登录时触发
    if (is_a($user, 'WP_User')) {
        // 初始化session
        if (!session_id()) {
            session_start();
        }
        
        $user_email = $user->user_email;
        $current_time = time();
        // 限制60秒内只能发送一次
        $last_send_time = isset($_SESSION['last_verification_send'][$user_email]) ? $_SESSION['last_verification_send'][$user_email] : 0;
        
        if ($current_time - $last_send_time > 60) {
            $verification_code = rand(100000, 999999);
            $subject = "登录验证码";
            $message = "你的登录验证码是:{$verification_code}";
            
            // 发送邮件
            $send_result = wp_mail($user_email, $subject, $message);
            
            // 记录发送时间
            $_SESSION['last_verification_send'][$user_email] = $current_time;
            
            // 可选:把验证码存在session里后续验证用
            $_SESSION['login_verification_code'][$user_email] = $verification_code;
        }
    }
    return $user;
}

额外注意事项

  • 如果是自定义登录表单,要确保表单提交时只触发一次请求,比如添加按钮禁用逻辑防止重复点击:
    <button type="submit" id="login-submit">登录</button>
    <script>
    document.getElementById('login-submit').addEventListener('click', function() {
        this.disabled = true;
        this.form.submit();
    });
    </script>
    
  • 检查主题或插件是否有重复加载这段代码的情况,不要同时把代码放在functions.php和自定义插件里。

内容的提问来源于stack exchange,提问作者MeladSharafi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 21:25:18