Search code examples
phploopswhile-loopphpmailer

Sending Bulk emails through phpmailer


I am using phpmailer to send bulk emails to my subscribers but I am facing a terrible problem that is when I send emails to my subscribers, each subscriber is getting the same email more than once. some are getting 4 times and some are getting 14 times. I am fetching subscriber emails where flag = 0 through Mysql table and at the end of the while loop I am updating subscriber flag to 1. I know its a issue of loop but I don't know where I am doing wrong or even not sure should I used while loop or something else to fix this issue. Any help would be highly grateful to me. here is my code:

<?php

$db_host = "localhost";
$db_username = "root";
$db_pass = "";
$link= mysqli_connect("$db_host","$db_username","$db_pass", "mydb") or die ("could not connect to mysql"); 

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
// Simply:

//Load Composer's autoloader
require 'vendor/autoload.php';

if(isset($_POST['send'])){

$mail = new PHPMailer(true);                              // Passing `true` enables exceptions
try {
     $query = "select customer_id, customer_name, customer_email from subscribers where flag_email = 0";
     $result = mysqli_query($link, $query) or die("No customer in the table");;

     while($values = mysqli_fetch_array($result)){
         $id = $values['customer_id'];
         $name = $values['customer_name'];
         $toemail = $values['customer_email'];


    //Server settings
    $mail->SMTPDebug = 1;                                 // Enable verbose debug output
    $mail->isSMTP();                                      // Set mailer to use SMTP
    $mail->Host = 'smtp server';  // Specify main and backup SMTP servers
    $mail->SMTPAuth = true;                               // Enable SMTP authentication
    $mail->Username = 'username';                 // SMTP username
    $mail->Password = 'password';                           // SMTP password
    $mail->SMTPSecure = 'tls';                            // Enable TLS encryption, `ssl` also accepted
    $mail->Port = 587;                                    // TCP port to connect to

    //Recipients
    $mail->setFrom('username', 'username');


    $mail->addReplyTo('myemail', 'name');

    $mail->addBCC(''.$toemail.'', ''.$name.'');

    //Content
    $mail->isHTML(true);                                  // Set email format to HTML
    $mail->Subject = 'Here is the subject';
    $mail->Body    = 'Here is the message';


    $mail->send();
    echo 'Message has been sent';
    $upd_query = "update subscribers set flag_email = 1 where customer_id = ".$id."";
    $result= mysqli_query($link, $upd_query);
}

} catch (Exception $e) {
    echo 'Message could not be sent. Mailer Error: ', $mail->ErrorInfo;
}


}

Solution

  • This is happening because you're not clearing the to addresses each time around your loop - notice the method is called addAddress, not setAddress, and it does what that suggests. You need to call $mail->clearAddresses(); at the end of your loop to reset it. You're doing things mostly right otherwise, but there are a few things you can do to improve efficiency, mainly using keep alive and setting all the properties that are common to all messages before your loop.

    You can see all this working in the mailing list example provided with PHPMailer.