Link to home
Start Free TrialLog in
Avatar of Robert Francis
Robert Francis

asked on

phpmailer in WHILE loop - weird results

I have a very simple page that should loop through a list of customers and send them each an email. Here is the code:

<?php include 'session.php';
require_once('class.phpmailer.php');
$mail = new PHPMailer();

$query = "SELECT email, fname FROM customers";
$results = mysqli_query($conn, $query);
while($row = mysqli_fetch_array($results)){
	$email = $row["email"];
	$fname = $row["fname"];
	$mail_body = '<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
<link href="css/.css" rel="stylesheet" type="text/css">
</head>
<body>
<html>
<body>
<div>
<p>Hello ' . $fname . ',</p>
<img src="http://jeffersonvillepigglywiggly.com/page1.jpg" width="90%">
<img src="http://jeffersonvillepigglywiggly.com/page2.jpg" width="90%">
<img src="http://jeffersonvillepigglywiggly.com/page3.jpg" width="90%">
<img src="http://jeffersonvillepigglywiggly.com/page4.jpg" width="90%">
<hr>
</div>
</body>
</html>
</body>
</html>';
$mail->IsSMTP(); 
$mail->SMTPDebug  = 2;
$mail->SMTPAuth   = true;                  
$mail->SMTPSecure = "tls";                 
$mail->Host       = "smtp.gmail.com";      
$mail->Port       = 587;                   
$mail->Username   = "jeffersonvillepigglywiggly@gmail.com"; 
$mail->Password   = "THE PASSWORD";   
$mail->SetFrom('pigglywiggly013@gmail.com', 'Jeffersonville Piggly Wiggly');
$mail->AddReplyTo("pigglywiggly013@gmail.com","Jeffersonville Piggly Wiggly");
$mail->Subject    = "Jeffersonville Piggly Wiggly";
$mail->AltBody    = "To view the message, please use an HTML compatible email viewer!"; // optional, comment out and test
$mail->MsgHTML($mail_body);
$address = $email;
$mail->AddAddress($address, $fname);
if(!$mail->Send()) {
  echo "Mailer Error: " . $mail->ErrorInfo;
} else {
  echo "Emails have been sent. Return to <a href=\"index.php\">Main Page</a>";
}?>
<?php  };//End of invoicing table?>

Open in new window


Here are the results displayed on the page after I run it:
SMTP -> FROM SERVER:220 smtp.gmail.com ESMTP g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER: 250-smtp.gmail.com at your service, [104.152.109.190] 250-SIZE 35882577 250-8BITMIME 250-STARTTLS 250-ENHANCEDSTATUSCODES 250-PIPELINING 250-CHUNKING 250 SMTPUTF8
SMTP -> FROM SERVER:220 2.0.0 Ready to start TLS
SMTP -> FROM SERVER: 250-smtp.gmail.com at your service, [104.152.109.190] 250-SIZE 35882577 250-8BITMIME 250-AUTH LOGIN PLAIN XOAUTH2 PLAIN-CLIENTTOKEN OAUTHBEARER XOAUTH 250-ENHANCEDSTATUSCODES 250-PIPELINING 250-CHUNKING 250 SMTPUTF8
SMTP -> FROM SERVER:250 2.1.0 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.1.5 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:354 Go ahead g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.0.0 OK 1483524169 g85sm105286275pfe.38 - gsmtp
Emails have been sent. Return to Main PageSMTP -> FROM SERVER:250 2.1.0 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.1.5 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.1.5 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:354 Go ahead g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.0.0 OK 1483524170 g85sm105286275pfe.38 - gsmtp
Emails have been sent. Return to Main PageSMTP -> FROM SERVER:250 2.1.0 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.1.5 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.1.5 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.1.5 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:354 Go ahead g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.0.0 OK 1483524172 g85sm105286275pfe.38 - gsmtp
Emails have been sent. Return to Main PageSMTP -> FROM SERVER:250 2.1.0 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.1.5 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.1.5 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.1.5 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.1.5 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:354 Go ahead g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.0.0 OK 1483524175 g85sm105286275pfe.38 - gsmtp
Emails have been sent. Return to Main PageSMTP -> FROM SERVER:250 2.1.0 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.1.5 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.1.5 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.1.5 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.1.5 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.1.5 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:354 Go ahead g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.0.0 OK 1483524177 g85sm105286275pfe.38 - gsmtp
Emails have been sent. Return to Main PageSMTP -> FROM SERVER:250 2.1.0 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.1.5 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.1.5 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.1.5 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.1.5 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.1.5 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.1.5 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:354 Go ahead g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.0.0 OK 1483524178 g85sm105286275pfe.38 - gsmtp
Emails have been sent. Return to Main PageSMTP -> FROM SERVER:250 2.1.0 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.1.5 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.1.5 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.1.5 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.1.5 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.1.5 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.1.5 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.1.5 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:354 Go ahead g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.0.0 OK 1483524179 g85sm105286275pfe.38 - gsmtp
Emails have been sent. Return to Main PageSMTP -> FROM SERVER:250 2.1.0 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.1.5 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.1.5 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.1.5 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.1.5 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.1.5 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.1.5 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.1.5 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.1.5 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:354 Go ahead g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.0.0 OK 1483524181 g85sm105286275pfe.38 - gsmtp
Emails have been sent. Return to Main PageSMTP -> FROM SERVER:250 2.1.0 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.1.5 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.1.5 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.1.5 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.1.5 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.1.5 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.1.5 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.1.5 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.1.5 OK g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:354 Go ahead g85sm105286275pfe.38 - gsmtp
SMTP -> FROM SERVER:250 2.0.0 OK 1483524183 g85sm105286275pfe.38 - gsmtp

It actually continues to grow and get bigger and bigger until it says:

Daily user sending quota exceeded. g85sm105286275pfe.38 - gsmtp

Not sure but I think it never made it through the list completely.

What seems to be my problem?
ASKER CERTIFIED SOLUTION
Avatar of Marcus Bointon
Marcus Bointon
Flag of France image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Sending emails with script have a number of issues that have nothing to do with code.

In most cases your ISP is going to limit how many emails you can send in a given time period - this is to prevent situations where malicious code hijacks your site and uses it to send out spam or malware.

There is usually a limit / minute on the number of emails - you would need to check with your ISP to find out if they are throttling outgoing email and what the limits are.

I would also look at putting the sending of emails in cron job. The script checks to see who has not been sent an email, gets the next N customers where N is the limit set by the ISP - sends the email, updates the status on the customer records to say the email has been sent and terminates. When it runs again (say every hour) it just picks up where it left off.
The problem is that you have everything in the loop, expecially AddAddress and Send functions: this makes your code to send email at each loop and each loop the number of recipientes increases of 1. SO the first recipient will receive as many emails as the total number of recipients, the second will receive as many emails as the total number -1 and so on.
In addition, you should keep the fixed part of mailer options outside the loop. In the loop you should have only addAddress function and the message which differs due to the variable $fname.
<?php include 'session.php';
require_once('class.phpmailer.php');
$mail = new PHPMailer();
$mail->IsSMTP(); 
$mail->SMTPDebug  = 2;
$mail->SMTPAuth   = true;                  
$mail->SMTPSecure = "tls";                 
$mail->Host       = "smtp.gmail.com";      
$mail->Port       = 587;                   
$mail->Username   = "jeffersonvillepigglywiggly@gmail.com"; 
$mail->Password   = "THE PASSWORD";   
$mail->SetFrom('pigglywiggly013@gmail.com', 'Jeffersonville Piggly Wiggly');
$mail->AddReplyTo("pigglywiggly013@gmail.com","Jeffersonville Piggly Wiggly");
$mail->Subject    = "Jeffersonville Piggly Wiggly";
$mail->AltBody    = "To view the message, please use an HTML compatible email viewer!"; // optional, comment out and test
$query = "SELECT email, fname FROM customers";
$results = mysqli_query($conn, $query);
while($row = mysqli_fetch_array($results)){
	$email = $row["email"];
	$fname = $row["fname"];
	$mail_body = '<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
<link href="css/.css" rel="stylesheet" type="text/css">
</head>
<body>
<html>
<body>
<div>
<p>Hello ' . $fname . ',</p>
<img src="http://jeffersonvillepigglywiggly.com/page1.jpg" width="90%">
<img src="http://jeffersonvillepigglywiggly.com/page2.jpg" width="90%">
<img src="http://jeffersonvillepigglywiggly.com/page3.jpg" width="90%">
<img src="http://jeffersonvillepigglywiggly.com/page4.jpg" width="90%">
<hr>
</div>
</body>
</html>
</body>
</html>';

$mail->MsgHTML($mail_body);
$address = $email;
$mail->AddAddress($address, $fname);
?>
<?php  }
if(!$mail->Send()) {
  echo "Mailer Error: " . $mail->ErrorInfo;
} else {
  echo "Emails have been sent. Return to <a href=\"index.php\">Main Page</a>";
}
//End of invoicing table?>

Open in new window

@Julian - in this case it has everything to do with the code.

@Marco - That's what calling clearAddresses solves, and what the mailing list example I pointed at does. That code you posted doesn't demonstrate this, is based on an obsolete example, and will not even run with a recent PHPMailer, so I'm not sure why you posted it!
@Marcus. I posted because it is up and running in a couple of my pages. clearAddresses is a good and even better solution for sure, but I don't understand why my code shouldn't work with recent versions of PHPMailer: what would prevent it to work?
It may work for you, but you're not sending to a list at all in the code you posted! PHPMailer versions from the last couple of years do not load the SMTP class automatically if your'e using `isSMTP()` - you either need to load PHPMailer's autoloader (or use composer), or load the SMTP class explicitly. You're doing neither of those things. It also suggests you're running an old version of PHPMailer yourself, so are likely to be open to several vulnerabilities, so I recommend upgrading. FWIW, I'm the maintainer of PHPMailer.
Fantastic, Marcus. Glad to meet you. You're totally right! I'll upgrade my version ASAP, even if in my scripts I don't need to sen to a list but to a number of recipients. Thank you for being in EE: it will be a pleasure to learn from your comments.
@Julian - in this case it has everything to do with the code.
I think we are facing more than one problem here.

1. there is the issue of the address list growing on each iteration.
2. We cannot ignore the following message
Daily user sending quota exceeded. g85sm105286275pfe.38 - gsmtp
Which indicates a throttle on emails sent.

While the clearAddresses solution may fix the multiple addressing there is a possibility that the original problem will remain.
Sure, but that's not what was asked about, and it seems likely that the multiplying factor is a primary cause of running out of quota. For example, a 10-user list would result in 1+2+3+4+5+6+7+8+9+10 = 55 messages being sent; for a 100  list it's 5,050!
Granted - but we don't know how big the actual list is. While this might result in the quota being exceeded more quickly it does not mean that having solved this the quota issue will not still be in play.

As I said before - we are looking at 2 potential issues here - there is sense in addressing both.