PHPMailer发送重复电子邮件

3

问题: 每个使用其电子邮件地址注册的用户都会收到三封重复的电子邮件。我的来宾名单被重复的电子邮件淹没了,我不知道我的代码出了什么问题。

可能原因: 我有3个注册表格,所以我认为当我提交一个注册表格时,它们都同时提交了。问题可能出在Bootstrap 4.1.3 JS或HTML中。

PHP代码:

$email = $_REQUEST['email'] ;

// Import PHPMailer classes into the global namespace
// These must be at the top of your script, not inside a function
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

require './PHPMailer-master/src/Exception.php';
require './PHPMailer-master/src/PHPMailer.php';
require './PHPMailer-master/src/SMTP.php';

// Popup Form Signup
$mail = new PHPMailer();
$mail->IsSMTP();
$mail->Host = "mail.domain.com";
$mail->SMTPAuth = true;
$mail->Username = "user@domain.com"; 
$mail->Password = "password"; 
$mail->SMTPSecure = 'TLS';                           
$mail->Port = 587;
$mail->From = $email;
$mail->setFrom('$email', 'Guest');
$mail->addAddress('admin@domain.com', 'Admin');
$mail->IsHTML(true);
$mail->Subject = "New Member!";
$mail->Body = $email;
$mail->AltBody = $email;

$mail2 = new PHPMailer();
$mail2->IsSMTP();
$mail2->Host = "mail.domain.com"; 
$mail2->SMTPAuth = true; 
$mail2->Username = "user@domain.com"; 
$mail2->Password = "password"; 
$mail2->SMTPSecure = 'TLS';                      
$mail2->Port = 587;                             
$mail2->setFrom('support@domain.com', 'Support');
$mail2->AddAddress("$email");    
$mail2->AddReplyTo('support@domain.com');

    $mail2->Subject = "Thanks for signing up!";
    $message = '';
    $mail2->Body = $message;
    $mail2->AltBody = $message;


    if(!$mail2->Send())
    {
    echo "Message could not be sent. Please reload the page and try again. <p>";
    echo "Mailer Error: " . $mail2->ErrorInfo;
    exit;
    }

    if(!$mail->Send())
    {
    echo "Message was not received. Please reload the page and try again.<p>";
    echo "Mailer Error: " . $mail->ErrorInfo;
    exit;
    }

我可以帮您翻译。以下是翻译结果,已保留HTML标签:

我还有其他表单打开不同的PHP文件,但它们不应该是这里的问题。我只是在这里添加了它,以防有人能找出什么问题。

表格1(相同的着陆页面)

<form class="signupForm1 input-group mt-1" method="post" action="topconfirm">
        <div class="input-group">
        <label for="email" class="sr-only">Enter your email address</label>
        <input style ="overflow:hidden;" id="email" type="email" name="email" required class="sentence form-control" aria-label="Large" placeholder="enter your email address">      
        <button style="font-size:17px;" name="topsubmit" type="submit" class="ctabutton semibolder submitButton sentence text-white btn btn-secondary px-lg-3 px-md-1 px-sm-1 btn-lg rounded-0">Get Started</button>
        </div>              
</form>

表格2(同一着陆页)

(注:保留HTML标签,不提供解释)
<form class="signupForm2 input-group mt-1" method="post" action="bottomconfirm">
                <div class="input-group">
                <label style="font-weight:normal!important;" for="email" class="sr-only">Enter your email address</label>
                <input style ="overflow:hidden;"  id="email" type="email" name="email" required class="sentence form-control" aria-label="Large" placeholder="enter your email address">         
                <input style="font-size:17px;" name="footersubmit" type="submit" class="ctabutton semibolder submitButton sentence text-white btn btn-secondary px-lg-3 px-md-1 px-sm-1 btn-lg rounded-0" value="Get Started"/>
                </div>              
        </form>

我不是JavaScript或PHP邮件专家,请有经验的人帮忙解决这个问题,我认为它可能与Bootstrap JS 4.13有关。非常感谢您的任何建议和帮助。谢谢!


2
你不需要初始化PHPMailer两次来发送两封电子邮件。你同时使用了php的mail()函数和phpmailer,这有点混乱,说实话。 - user10226920
1
在不同形式中具有相同名称的输入不应该有影响。您一次只能提交一个表单。 - Don't Panic
确认触发 confirm.php 页面,当输入有效的电子邮件并点击提交按钮时发送电子邮件。 - ChosenJuan
1
如果你使用变量并根据 if(isset($_POST['variable'])) 条件进行替换,phpmailer的代码可以简化到大约一半。 - comphonia
我真的不知道区别,你能给我提供一段代码示例吗?你说的PHP Mail和PHP Mailer是什么意思?我在PHP方面是个新手。 - ChosenJuan
显示剩余10条评论
8个回答

2
尝试为每个按钮创建单独的submit()函数(使用onclick处理程序),并从它们中删除value ='submit',如下所示:
    <!--signupform1-->
    <form class="signupForm1 input-group mt-1" method="post" action="topconfirm">
        <div class="input-group">
            <label for="email" class="sr-only">Enter your email address</label>
            <input style ="overflow:hidden;" id="email" type="email" name="email" required class="sentence form-control" aria-label="Large" placeholder="enter your email address">      
            <button style="font-size:17px;" name="topsubmit" type="button" class="ctabutton semibolder submitButton sentence text-white btn btn-secondary px-lg-3 px-md-1 px-sm-1 btn-lg rounded-0" onclick="submit1();">Get Started</button>
        </div>              
    </form>

    <!--signupform2-->
    <form class="signupForm2 input-group mt-1" method="post" action="bottomconfirm">
        <div class="input-group">
            <label style="font-weight:normal!important;" for="email" class="sr-only">Enter your email address</label>
            <input style ="overflow:hidden;"  id="email" type="email" name="email" required class="sentence form-control" aria-label="Large" placeholder="enter your email address">         
            <input style="font-size:17px;" name="footersubmit" type="button" class="ctabutton semibolder submitButton sentence text-white btn btn-secondary px-lg-3 px-md-1 px-sm-1 btn-lg rounded-0" onclick="submit2();" value="Get Started"/>
        </div>              
    </form>

然后在你的js文件中:

<script>
    function submit1() {
        $(".signupForm1").submit();
    }
    function submit2() {
        $(".signupForm2").submit();
    }
</script>

这个答案最好,问题出在提交按钮上。然而,为了让它正常工作,我不得不在两个表单的按钮上添加type="submit"。到目前为止,我已经从每个表单中收到了单独的电子邮件。干杯!谢谢你的答案! - ChosenJuan

1
首先:Bootstrap不是罪魁祸首,JS也不是。如果PHP(或php mailer)也干净,那么您可能需要查看邮件服务器设置(与您的主机进行检查)。
然而,也许表单被提交了两次? 让我们来检查一下:
  1. 打开Google Chrome调试器(F12)
  2. 点击“网络”,勾选“保留日志”
  3. 点击“清除”(左侧第二个图标)
  4. 运行您的常规脚本(即填写表单并提交)
  5. “网络”选项卡将向您显示任何重复调用您的PHP页面
如果仍然失败,请尝试以下操作:
下载 https://github.com/PHPMailer/PHPMailer 创建一个完全空白的文件,直接放置您的PHP发送电子邮件代码。删除表单、输入、JavaScript、isset和其他内容。通过简单地调用该文件来运行它,因此它将如下所示:
    require_once("PHPMailerAutoload.php"); // <---- only this will be required (put your path properly)

    $mail2 = new PHPMailer();
    $mail2->IsSMTP();
    $mail2->Host = "mail.domain.com"; 
    $mail2->SMTPAuth = true; 
    $mail2->Username = "user@domain.com"; 
    $mail2->Password = "password"; 
    $mail2->SMTPSecure = 'TLS';                      
    $mail2->Port = 587;                             
    $mail2->setFrom('support@domain.com', 'Support');
    $mail2->AddAddress("$email");    
    $mail2->AddReplyTo('support@domain.com');

    $mail2->Subject = "Thanks for signing up!";
    $message = '';
    $mail2->Body = $message;
    $mail2->AltBody = $message;


    if(!$mail2->Send())
    {
    echo "Message could not be sent. Please reload the page and try again. 
    <p>";
    echo "Mailer Error: " . $mail2->ErrorInfo;
    exit;
    }

祝你好运


谢谢你的调试教程,非常有价值。然而,我的日志并没有显示出我在提交邮件表单时代码有什么问题。看起来需要一个JS解决方案来修复它。无论如何,还是谢谢! - ChosenJuan
@ChosenJuan 我猜大多数人都忽略了这一点:首先,我们不应该将JS表单提交事件绑定到HTML提交按钮上。 :D - DingDong

0

start a session in your server and store the mail sent information

// Import PHPMailer classes into the global namespace
// These must be at the top of your script, not inside a function
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

require './PHPMailer-master/src/Exception.php';
require './PHPMailer-master/src/PHPMailer.php';
require './PHPMailer-master/src/SMTP.php';

// Popup Form Signup
$mail = new PHPMailer();
$mail->IsSMTP();
$mail->Host = "mail.domain.com";
$mail->SMTPAuth = true;
$mail->Username = "user@domain.com"; 
$mail->Password = "password"; 
$mail->SMTPSecure = 'TLS';                           
$mail->Port = 587;
$mail->From = $email;
$mail->setFrom('$email', 'Guest');
$mail->addAddress('admin@domain.com', 'Admin');
$mail->IsHTML(true);
$mail->Subject = "New Member!";
$mail->Body = $email;
$mail->AltBody = $email;

$mail2 = new PHPMailer();
$mail2->IsSMTP();
$mail2->Host = "mail.domain.com"; 
$mail2->SMTPAuth = true; 
$mail2->Username = "user@domain.com"; 
$mail2->Password = "password"; 
$mail2->SMTPSecure = 'TLS';                      
$mail2->Port = 587;                             
$mail2->setFrom('support@domain.com', 'Support');
$mail2->AddAddress("$email");    
$mail2->AddReplyTo('support@domain.com');

    $mail2->Subject = "Thanks for signing up!";
    $message = '';
    $mail2->Body = $message;
    $mail2->AltBody = $message;


if(!$_SESSION['is_mail_1_send']){//check mail sended once
    if(!$mail2->Send())
    {
    echo "Message could not be sent. Please reload the page and try again. <p>";
    echo "Mailer Error: " . $mail2->ErrorInfo;
   $_SESSION['is_mail_1_send']=false;
 exit;
    }else{
            $_SESSION['is_mail_1_send']=true;   
    }
}
if(!$_SESSION['is_mail_2_send']){//check mail sended once
    if(!$mail->Send())
    {
    echo "Message was not received. Please reload the page and try again.<p>";
    echo "Mailer Error: " . $mail->ErrorInfo;
$_SESSION['is_mail_2_send']=false;
    exit;
    }else{
        $_SESSION['is_mail_2_send']=true;
    }
}

?>


这个不起作用,它仍然会发送重复的电子邮件。这个应该把日志发送到我的邮箱吗? - ChosenJuan
通过使用我的会话设置,您收到了多少封电子邮件?我尝试了我的代码,只发送了2封邮件。 - Mahfuzar Rahman
它一直从support@domain.com向用户发送三封重复的电子邮件,并向我的admin@domain.com发送三封重复的电子邮件。 - ChosenJuan

0
你在哪里处理表单提交事件?创建一个单独的函数来发送邮件。当用户点击特定的表单提交按钮时,调用该函数,如下所示:
// Your separate Mail sending function
sendMail(arg1, arg2, arg3){
   // PHP Mailer Configurations
}

// Calling your first form
if(isset($_POST['topsubmit']){
  sendMail(arg1, arg2, arg3);
}

// Calling your second form
if(isset($_POST['footersubmit']){
  sendMail(arg1, arg2, arg3);
}

你能详细说明如何将上述代码整合吗?我只需复制sendmail部分并将其放在上面还是应该替换某些东西?第二个代码只需替换if(!$ mail-> Send())代码吗?你能更新一下你的示例吗? - ChosenJuan
如果(isset($_POST['topsubmit']){ if(!$mail->Send()) // 像这样应该可以工作。 }// 但是,如果你将与邮件相关的完整配置发送到一个单独的函数中,效果会更好。 - Himel Rana
我能否只添加这个send函数来替换掉两个if(!$mail->Send())函数?// 调用第一个表单 如果(isset($_POST['topsubmit']){ sendMail($mail, $mail2); echo "无法发送消息。请返回voozlr.com并重试。如果问题仍然存在,请在voozlr.com/contact与我们联系。感谢您的耐心!<p>"; echo "邮件程序错误:" . $mail, $mail2->ErrorInfo; exit; } - ChosenJuan
如果(isset($_POST['footersubmit']){ if(!$mail2->Send()) { echo "无法发送消息。请返回voozlr.com并重试。如果问题仍然存在,请联系我们:voozlr.com/contact。感谢您的耐心!<p>"; echo "邮件发送错误:" . $mail2->ErrorInfo; exit; }它不起作用。我做错了什么吗?还是我漏掉了什么? - ChosenJuan

0

我理解得对吗? o_O

当然,使用那段 PHP 代码,你可以发送多封电子邮件。

只需将你的 PHP 代码更改为以下形式,这样你就可以有条件地解析 mail1mail2

if (!empty($_POST['topsubmit']))
{
    $mail2 = new PHPMailer();
    ...
    if(!$mail2->Send())
    ...
}

if (!empty($_POST['footersubmit']))
{
    $mail2 = new PHPMailer();
    ...
    if(!$mail2->Send())
    ...
}

因此,所有的电子邮件不会在同一次页面加载时发送。

我同时发送两封电子邮件。一封电子邮件:$mail 发送给 admin.domain.com 上的自己,另一封电子邮件:$mail2 发送给输入其邮箱的用户。但是您回答的是将顶部提交和底部提交拆分,而我将顶部提交和底部提交拆分为名为 topconfirm.php 和 footerconfirm.php 的单独的 PHP 文件,这两个 PHP 文件都会发送两封电子邮件,分别是 mail 和 mail2,分别发送给新注册的用户和我自己。请问如何设置? - ChosenJuan

0

这是对我的问题的完整答案,感谢@SearchingSolutions向我展示了解决这个问题的正确方法。

我为了解决这个问题所做的是创建了两个不同的按钮,每个按钮都有单独的onclick处理程序。每个按钮都有不同的id,并且我在两个按钮上都添加了TYPE="Submit"。我给每个表单都起了不同的名字,并且在特定的onclick处理程序被调用时,添加了一个小的JS脚本来提交特定的表单。

到目前为止,每封电子邮件都按预期到达,一切都重新运行顺利。

非常感谢大家提供的出色答案!

HTML代码:

<form class="signupForm1 input-group mt-1" method="post" action="topconfirm">
        <div class="input-group">
        <label for="email2" class="sr-only">Enter your email address</label>
        <input style ="overflow:hidden;" id="email2" type="email" name="email2" required class="sentence form-control" aria-label="Large" placeholder="enter your email address">        
        <button style="font-size:17px;" name="topsubmit" type="submit" class="ctabutton semibolder sentence text-white btn btn-secondary px-lg-3 px-md-1 px-sm-1 btn-lg rounded-0" onclick="submit1();">Get Started"</button>
        </div>              
</form>


<form class="signupForm2 input-group mt-1" method="post" action="footerconfirm">
        <div class="input-group">
        <label style="font-weight:normal!important;" for="email3" class="sr-only">Enter your email address</label>
        <input style ="overflow:hidden;"  id="email3" type="email" name="email3" required class="sentence form-control" aria-label="Large" placeholder="enter your email address">       
        <button style="font-size:17px;" name="footersubmit" type="submit" class="ctabutton semibolder sentence text-white btn btn-secondary px-lg-3 px-md-1 px-sm-1 btn-lg rounded-0" onclick="submit2();">Get Started"</button>
        </div>              
</form>

JS脚本:

<script>
function submit1() {
    $(".signupForm1").submit();
}
function submit2() {
    $(".signupForm2").submit();
}


0
我认为深入研究你的jQuery / JS代码可能会找到答案,但我猜测你表单中的

我尝试将输入更改为提交,但这也不起作用。唯一可能有问题的JQuery代码可能是我将很快发布的Jquery验证代码。 - ChosenJuan

0

我不知道你使用的是哪个版本的PHPMailer,但你同时也在使用PHP的mail()方法,这真是相当讽刺,因为你也在使用PHPMailer。但无论如何,在我的一个项目中,我是这样做的:

function sendAuthEmail($email, $token, $role) {
        try {
            $mail = new PHPMailer(true);
            $mail->SMTPDebug = 0; //SMTP Debug
            $mail->isSMTP();
            $mail->Host = "smtp.gmail.com";
            $mail->SMTPAuth = true;
            $mail->Username = 'example@example.com';
            $mail->Password = 'password';
            $mail->SMTPSecure = 'tls';
            $mail->Port = '587';
            /**
             * SMTPOptions work-around by @author : Synchro
             * This setting should removed on server and
             * mailing should be working on the server
             */
            $mail->SMTPOptions = array(
                'ssl' => array(
                    'verify_peer' => false,
                    'verify_peer_name' => false,
                    'allow_self_signed' => true
                )
            );

            // Recipients

            $mail->setFrom('no-reply@confirmation.com', 'Do Not Reply');
            $mail->addAddress($email, 'Yash Karanke'); // Add a recipient
            $mail->addReplyTo('no-reply@confirmation.com');

            // Content

            $mail->isHTML(true); // Set email format to HTML
            $mail->Subject = 'Authentication Email';
            $mail->Body = 'text to send';
            if ($mail->send()) {
                return true;
            }
            else {
                return false;
                exit();
            }
        }

        catch(Exception $e) {
            return $mail->ErrorInfo;
        }
    }

如果你正在寻找一个更简单的例子,可以移除封装的函数,只使用你需要的代码。更多详细信息可参见文档

在你的代码中,你使用了if(!$mail->send())这部分我不确定它是如何工作的,但你应该使用if($mail->send()),这是文档推荐的方式。

这段代码片段来自6.0.3版本。


当我注释掉mail($to, $subject, $message, $headers);时,它不起作用,但是我删除了$email = $_REQUEST['email'];之后,它可以正常工作。然而,你上面的解决方案并不起作用,我仍然收到重复的电子邮件。 - ChosenJuan
请检查更新后的PHPMailer代码,我现在认为问题与jQuery提交脚本有关。告诉我你的想法。 - ChosenJuan
@ChosenJuan 是的,我已经检查过了,jQuery代码没有冲突。 - user10415043
是的,我实际上完全移除了jQuery,它甚至都不是必需的。我认为问题在于它同时提交了所有三个表单,但是我不知道如何在保留所有三个表单的情况下解决这个问题。有什么想法吗? - ChosenJuan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接