WordPress中如何按条件为PHPMailer切换SMTP发信账号
WordPress 不同场景切换SMTP发件账号实现
问题说明
- 运行环境:WordPress v6.0,已通过
phpmailer_init钩子配置全局默认SMTP账号no-reply@example.com,当前运行正常 - 需求:站点自定义联系表单通过
wp_mail()发出的邮件,单独使用contact@example.com这个SMTP账号发送 - 现有联系表单发信代码:
wp_mail($form_to, $form_subject, $form_body, implode("\r\n", $form_headers));
- 现有钩子代码缺少场景判断逻辑,无法区分普通系统邮件和联系表单邮件。
实现方法
最稳妥的方案是给联系表单的邮件加专属标识,钩子检测到标识就切换SMTP配置,不影响其他场景发信。
方案1:自定义邮件头标识(推荐,无兼容问题)
首先修改联系表单的wp_mail调用,在邮件头里加自定义标识,自定义头统一用X-开头避免和标准邮件头冲突:
// 在原有$form_headers数组中追加标识头 $form_headers[] = 'X-Mail-Source: contact_form'; // 原有发信逻辑不变 wp_mail($form_to, $form_subject, $form_body, implode("\r\n", $form_headers));
然后替换你原来phpmailer_init函数里的占位判断逻辑,检测这个自定义头即可:
add_action('phpmailer_init', 'send_smtp_email', 10, 1); function send_smtp_email($phpmailer) { $phpmailer->isSMTP(); $phpmailer->isHTML(true); // 检测是否为联系表单邮件 $is_contact = false; foreach ((array)$phpmailer->CustomHeader as $header_item) { if ( !empty($header_item[0]) && $header_item[0] === 'X-Mail-Source' && !empty($header_item[1]) && $header_item[1] === 'contact_form' ) { $is_contact = true; break; } } if ($is_contact) { // 联系表单专属SMTP配置 $phpmailer->Host = 'smtp.example.com'; $phpmailer->SMTPAuth = true; $phpmailer->Port = 465; $phpmailer->Username = 'contact@example.com'; $phpmailer->Password = 'password1'; $phpmailer->SMTPSecure = 'ssl'; $phpmailer->From = 'contact@example.com'; $phpmailer->FromName = 'Site Contact Form'; } else { // 默认全局SMTP配置 $phpmailer->Host = 'smtp.example.com'; $phpmailer->SMTPAuth = true; $phpmailer->Port = 465; $phpmailer->Username = 'no-reply@example.com'; $phpmailer->Password = 'password2'; $phpmailer->SMTPSecure = 'ssl'; $phpmailer->From = 'no-reply@example.com'; $phpmailer->FromName = 'Site Mail'; } }
注:你原代码里
SMTPAuth传的是字符串'true',这里改成了布尔值true,符合PHPMailer的参数规范,避免部分环境出现兼容问题。
方案2:全局变量标识(适合不方便修改邮件头的场景)
如果不想改动邮件头,可以用全局变量做临时标记,在联系表单调用wp_mail()前后设置和重置标识:
// 设置联系表单标识 global $current_mail_source; $current_mail_source = 'contact_form'; // 执行发信 wp_mail($form_to, $form_subject, $form_body, implode("\r\n", $form_headers)); // 发信完成后重置标识,避免影响后续其他邮件 $current_mail_source = '';
对应的判断逻辑直接读全局变量即可:
global $current_mail_source; if ($current_mail_source === 'contact_form') { // 加载联系表单SMTP配置 }
注意:全局变量方案存在标识串扰风险,如果发信流程中被其他逻辑提前中断,可能导致后续邮件错误使用联系表单的SMTP配置,优先选自定义邮件头的方案。
内容的提问来源于stack exchange,提问作者theKing
相关产品推荐
相关产品推荐

