PHPmailer -多次发送电子邮件

时间:2022-11-15 10:43:43

I am sending emails using PHPmailer. As of now, I am successful in sending email to one address. Now, I want to send multiple emails in just one click.

我正在用PHPmailer发邮件。到目前为止,我已经成功地将邮件发送到一个地址。现在,我想在一次点击中发送多个电子邮件。

PROBLEM: I have tried to use some loops below to send multiple email but I get wrong outpout. Yes, it sends email but to only one address, and the email address is getting all of the emails that are supposed to be emailed to other emails.

问题:我尝试使用下面的一些循环来发送多个电子邮件,但是我得到了错误的输出。是的,它只发送电子邮件到一个地址,而电子邮件地址是接收所有应该发送到其他电子邮件的电子邮件。

For example, when I send 17 emails, those 17 emails are sent to only one address. The emails should be sent according to the addresses in the database, with corresponding unique attachments. Example: abc@gmail.com should have abc.pdf attached, and 123@gmail.com should have 123.pdf attached.

例如,当我发送17封邮件时,这17封邮件只发送到一个地址。电子邮件应该按照数据库中的地址发送,并带有相应的唯一附件。示例:abc@gmail.com应该有abc。pdf附件,123@gmail.com应该有123pdf。

I think it's in the loop. Please help me figure it out. Thanks.

我认为它在循环中。请帮我弄清楚。谢谢。

require_once('phpmailer/class.phpmailer.php');
include("phpmailer/class.smtp.php"); 

$mail             = new PHPMailer();

$body             = file_get_contents('phpmailer/body.html');
$body             = preg_replace('/\/b]/','',$body);

$file ='phpmailer/mailpass.txt';
    if($handle = fopen($file,"r")){
        $contentpass = fread($handle,'15');
        fclose($handle);
        }

$mail->IsSMTP(); 
$mail->Host       = "smtp.gmail.com"; 
$mail->SMTPDebug  = 1;                   

$mail->SMTPAuth   = true;                  
$mail->SMTPSecure = "tls";                 
$mail->Host       = "smtp.gmail.com";      
$mail->Port       = 587;                   
$mail->Username   = "email@gmail.com";  
$mail->Password   = $contentpass;           

$mail->SetFrom("email@gmail.com", "Subject");

$mail->AddReplyTo("email@gmail.com","Subject");

$mail->Subject    = "Subjects";

$mail->AltBody    = "Subject";

$mail->MsgHTML($body);


$file='current_schoolyear.txt';
    if($handle = fopen($file,"r"))
    {
        $content = fread($handle,'9');
            fclose($handle);
    }



$input = addslashes($_POST['depchair']);                        


$email = "select email_address  from sa_student where schoolyear = '$input'"; 



if ($p_address=mysql_query($email))
{ 



  while($row = mysql_fetch_assoc($p_address))
  {



    $mail->AddAddress($row['email_address']);

    $input = addslashes($_POST['depchair']);                                                                                    

    $control = "select control_no  from sa_student where schoolyear = '$input'";

    if($ctrl=mysql_query($control)){

        $ctrl_no = mysql_result($ctrl, 0);


        $mail->AddAttachment("fpdf/pdf_reports/document/".$ctrl_no.".pdf");  


    }
    else
    {

        echo "No attached document.";

    }

            if(!$mail->Send()) {
                    $message = "<div class=\"nNote nFailure\" >
                                    <p>Error sending email. " . $mail->ErrorInfo ."</p>
                                </div>";

            } else { 
                    $message = "<div class=\"nNote nSuccess\" >
                                    <p> Email have been sent to the examinees in ".$input_depchair. "! </p>
                                </div>";                            

                        }



       }

    }



else
{
    echo (mysql_error ());
}

UPDATED CODE: After running the code below, I was able to send an email and with the correct attachment. However, there was only ONE email sent (the last email address in the database), and the rest of the emails were not sent.

更新代码:运行下面的代码后,我可以发送电子邮件和正确的附件。但是,只发送了一封电子邮件(数据库中的最后一个电子邮件地址),其余的邮件没有发送。

$input = addslashes($_POST['depchair']);                        


$email = "select email_address, control_no  from sa_student where schoolyear = '$input'"; 



if ($p_address=mysql_query($email))
{ 



  while($row = mysql_fetch_assoc($p_address))
  {

    $cloned = clone $mail;

    $cloned->AddAddress($row['email_address']);




        $cloned->AddAttachment("fpdf/pdf_reports/document/".$row['control_no'].".pdf");  




            if(!$cloned->Send()) {
                    $message = "<div class=\"nNote nFailure\" >
                                    <p>Error sending email. " . $mail->ErrorInfo ."</p>
                                </div>";

            } else { 
                    $message = "<div class=\"nNote nSuccess\" >
                                    <p> Email have been sent to the examinees in ".$input_depchair. "! </p>
                                </div>";                            

                        }
unset( $cloned );


       }

    }



else
{
    echo (mysql_error ());
}

2 个解决方案

#1


2  

After you send an email $mail->Send(), execute this:

发送邮件$mail-> send()后,执行以下操作:

$mail->ClearAllRecipients();

in your while loop.
So your basic while loop structure looks like this:

while循环。所以你的基本while循环结构是这样的:

while($row = mysql_fetch_assoc($p_address)){

    $mail->AddAddress($row['email_address']);
    $mail->AddAttachment("fpdf/pdf_reports/document/".$ctrl_no.".pdf");
    $mail->send();
    $mail->ClearAllRecipients(); 
    $mail->ClearAttachments();   //Remove all attachements

}

#2


2  

Within your loop, create a clone of the $mail object - before you add the recipient and attachment - then use the clone to send the email. The next loop iteration will create a new clone free of the previous address and attachment:

在循环中,创建$mail对象的克隆——在添加收件人和附件之前——然后使用克隆发送电子邮件。下一个循环迭代将创建一个没有以前地址和附件的新克隆:

while($row = mysql_fetch_assoc($p_address)) {

    $cloned = clone $mail;

    $cloned->AddAddress($row['email_address']);

    // add attchment to $cloned, etc.

    if ( $cloned->send() ) { /* etc */ }

    unset( $cloned );

}

This will "clear" your per-iteration changes (like address, attachment, etc) without you having to reenter config properties (like, from, host, etc.)

这将“清除”每次迭代的更改(比如地址、附件等),而不需要重新输入配置属性(比如,from、host等)。

Addendum:

附录:

Your attachments will likely be all the same because you're not fetching new results for these lines (within your loop):

您的附件很可能是相同的,因为您没有为这些行获取新的结果(在您的循环中):

$input=addslashes($_POST['depchair']);

$control = "select control_no  from sa_student where schoolyear = '$input'";

if ($ctrl=mysql_query($control)) {

    $ctrl_no = mysql_result($ctrl, 0);

    $mail->AddAttachment("fpdf/pdf_reports/document/".$ctrl_no.".pdf");

}

$ctrl_no will always return the same result because (I'm assuming) $_POST['depchair'] does not change - thus $input, $control, $ctrl, and $ctrl_no all remain (effectively) the same for each loop. You need to find whatever it is your actually intend to be the $ctrl_no for each loop - right now you're using the same one over and over.

$ctrl_no将总是返回相同的结果,因为(我假设)$_POST['depchair']不会改变——因此,对于每个循环,$input、$control、$ctrl和$ctrl_no都(有效地)保持相同。您需要为每个循环找到您真正想要的值$ctrl_no—现在您正在一遍又一遍地使用相同的值。

The following query could probably help:

以下查询可能有帮助:

// replace
// $email = "select email_address  from sa_student where schoolyear = '$input'";

// with:
$students_query = "select email_address, control_no from sa_student where schoolyear = '$input'";

// then
// if ($p_address=mysql_query($email)) {
// while($row = mysql_fetch_assoc($p_address)) {

// becomes
if ( $students=mysql_query($students_query) ) {
while ( $row = mysql_fetch_assoc( $students ) ) {

// so that finally, etc
$cloned->AddAddress($row['email_address']);
$ctrl_no = $row['control_no'];

This pulls both the student email address and their control_no in the same query, making sure they stay associated with each other through the loop. You can then get rid of the second mid-loop query, since all the results you need were pulled in the first out-of-loop query. The above isn't all the code you need to change, just the critical parts.

这将把学生的电子邮件地址和它们的control_no都拉到同一个查询中,以确保它们通过循环保持关联。然后可以删除第二个中循环查询,因为在第一个外循环查询中提取了所有需要的结果。以上并不是您需要更改的所有代码,只是关键部分。

#1


2  

After you send an email $mail->Send(), execute this:

发送邮件$mail-> send()后,执行以下操作:

$mail->ClearAllRecipients();

in your while loop.
So your basic while loop structure looks like this:

while循环。所以你的基本while循环结构是这样的:

while($row = mysql_fetch_assoc($p_address)){

    $mail->AddAddress($row['email_address']);
    $mail->AddAttachment("fpdf/pdf_reports/document/".$ctrl_no.".pdf");
    $mail->send();
    $mail->ClearAllRecipients(); 
    $mail->ClearAttachments();   //Remove all attachements

}

#2


2  

Within your loop, create a clone of the $mail object - before you add the recipient and attachment - then use the clone to send the email. The next loop iteration will create a new clone free of the previous address and attachment:

在循环中,创建$mail对象的克隆——在添加收件人和附件之前——然后使用克隆发送电子邮件。下一个循环迭代将创建一个没有以前地址和附件的新克隆:

while($row = mysql_fetch_assoc($p_address)) {

    $cloned = clone $mail;

    $cloned->AddAddress($row['email_address']);

    // add attchment to $cloned, etc.

    if ( $cloned->send() ) { /* etc */ }

    unset( $cloned );

}

This will "clear" your per-iteration changes (like address, attachment, etc) without you having to reenter config properties (like, from, host, etc.)

这将“清除”每次迭代的更改(比如地址、附件等),而不需要重新输入配置属性(比如,from、host等)。

Addendum:

附录:

Your attachments will likely be all the same because you're not fetching new results for these lines (within your loop):

您的附件很可能是相同的,因为您没有为这些行获取新的结果(在您的循环中):

$input=addslashes($_POST['depchair']);

$control = "select control_no  from sa_student where schoolyear = '$input'";

if ($ctrl=mysql_query($control)) {

    $ctrl_no = mysql_result($ctrl, 0);

    $mail->AddAttachment("fpdf/pdf_reports/document/".$ctrl_no.".pdf");

}

$ctrl_no will always return the same result because (I'm assuming) $_POST['depchair'] does not change - thus $input, $control, $ctrl, and $ctrl_no all remain (effectively) the same for each loop. You need to find whatever it is your actually intend to be the $ctrl_no for each loop - right now you're using the same one over and over.

$ctrl_no将总是返回相同的结果,因为(我假设)$_POST['depchair']不会改变——因此,对于每个循环,$input、$control、$ctrl和$ctrl_no都(有效地)保持相同。您需要为每个循环找到您真正想要的值$ctrl_no—现在您正在一遍又一遍地使用相同的值。

The following query could probably help:

以下查询可能有帮助:

// replace
// $email = "select email_address  from sa_student where schoolyear = '$input'";

// with:
$students_query = "select email_address, control_no from sa_student where schoolyear = '$input'";

// then
// if ($p_address=mysql_query($email)) {
// while($row = mysql_fetch_assoc($p_address)) {

// becomes
if ( $students=mysql_query($students_query) ) {
while ( $row = mysql_fetch_assoc( $students ) ) {

// so that finally, etc
$cloned->AddAddress($row['email_address']);
$ctrl_no = $row['control_no'];

This pulls both the student email address and their control_no in the same query, making sure they stay associated with each other through the loop. You can then get rid of the second mid-loop query, since all the results you need were pulled in the first out-of-loop query. The above isn't all the code you need to change, just the critical parts.

这将把学生的电子邮件地址和它们的control_no都拉到同一个查询中,以确保它们通过循环保持关联。然后可以删除第二个中循环查询,因为在第一个外循环查询中提取了所有需要的结果。以上并不是您需要更改的所有代码,只是关键部分。