WordPress中点击按钮调用wp_mail()发送邮件失败排查求助
问题分析与修复方案
先梳理下你代码里的核心问题,这是导致功能失效的主要原因:
1. wp_mail 参数逻辑错误(最关键)
你当前把用户输入的姓名当成了收件人邮箱($to = esc_attr($_POST["name"])),这完全不符合邮件发送逻辑——wp_mail 的第一个参数 $to 需要是你要接收邮件的目标邮箱地址,而不是提交表单用户的姓名。
另外,邮件头 $headers 的格式也不符合要求,WordPress 要求 headers 是标准的邮件格式,比如 From: 发件人名称 <发件人邮箱>,你直接传用户输入的邮箱字符串,会导致发件人配置失效。
2. 表单数据处理不规范
- 使用
esc_attr处理表单数据不合适,应该针对字段类型用对应 sanitize 函数:邮箱用sanitize_email,普通文本用sanitize_text_field,文本域用sanitize_textarea_field。 - 缺少基本的字段非空验证和邮箱格式验证,无法判断用户输入是否合法。
3. Gmail SMTP 的潜在配置问题
如果你的 Google 账号开启了2步验证,直接用账号密码无法通过 SMTP 验证,需要生成应用专用密码替代 SMTP_PASS;如果没开2FA,需要在账号设置里临时开启「不太安全的应用访问」(更推荐开启2FA并使用应用专用密码)。
修正后的完整代码
1. 表单与邮件发送函数修正
function send_mail_form(){ // 处理表单提交 if( isset($_POST["send"]) && !empty($_POST["send"]) ){ // 验证并清理表单数据 $sender_name = sanitize_text_field($_POST["name"]); $sender_email = sanitize_email($_POST["email"]); $subject = sanitize_text_field($_POST["subject"]); $message = sanitize_textarea_field($_POST["message"]); // 基本字段验证 $errors = []; if( empty($sender_name) ) $errors[] = "请输入您的姓名"; if( !is_email($sender_email) ) $errors[] = "请输入有效的邮箱地址"; if( empty($subject) ) $errors[] = "请输入邮件主题"; if( empty($message) ) $errors[] = "请输入邮件内容"; if( empty($errors) ){ // 替换成你自己的目标收件邮箱 $to = "your-receive-email@example.com"; // 正确设置邮件头 $headers = [ "From: {$sender_name} <{$sender_email}>", "Content-Type: text/html; charset=UTF-8" ]; // 发送邮件并判断结果 $mail_sent = wp_mail($to, $subject, nl2br($message), $headers); if( $mail_sent ){ echo "<div style='padding:10px; background:#d4edda; color:#155724; border-radius:4px;'>邮件发送成功!</div>"; } else { echo "<div style='padding:10px; background:#f8d7da; color:#721c24; border-radius:4px;'>邮件发送失败,请稍后重试!</div>"; } } else { // 显示错误提示 echo "<div style='padding:10px; background:#f8d7da; color:#721c24; border-radius:4px;'>"; foreach($errors as $error){ echo "<p>{$error}</p>"; } echo "</div>"; } } // 输出表单 ?> <form action="" method="post"> <input type="text" name ="name" id="name" class="name" placeholder="your name" required><br /> <input type="email" name ="email" id="email" class="email" placeholder="your email" required><br /> <input type="text" name="subject" id="subject" class="subject" placeholder="your subject" required><br /> <textarea name="message" id="message" placeholder="your message" cols="30" rows="10" required></textarea> <?php submit_button('Send', 'primary', 'send'); ?> </form> <?php } add_shortcode('send_mail_form', 'send_mail_form');
2. SMTP 配置修正
如果是 Gmail SMTP,替换 SMTP_PASS 为应用专用密码(开启2FA后生成):
define( 'SMTP_USER', 'hendratrisno@gmail.com' ); define( 'SMTP_PASS', 'your-app-specific-password' ); // 替换成你的应用专用密码 define( 'SMTP_HOST', 'smtp.gmail.com' ); define( 'SMTP_FROM', 'hendratrisno@gmail.com' ); define( 'SMTP_NAME', 'Hendra' ); define( 'SMTP_PORT', '587' ); define( 'SMTP_SECURE', 'TLS' ); define( 'SMTP_AUTH', true );
额外安全建议
可以添加 nonce 字段防止 CSRF 攻击,让表单更安全:
- 在表单里添加:
<?php wp_nonce_field('send_mail_nonce', 'mail_nonce'); ?> - 在处理提交时,增加验证逻辑:
if( !wp_verify_nonce($_POST['mail_nonce'], 'send_mail_nonce') ){ echo "<div style='padding:10px; background:#f8d7da; color:#721c24; border-radius:4px;'>请求验证失败,请重新提交!</div>"; return; }
内容的提问来源于stack exchange,提问作者Hendra
相关产品推荐
相关产品推荐

