I'm using the example mailing list and trying to tailor it to work with my DB. The problem I'm having is it's only sending to one email from the list of users in the Table (the example table only has 5 users). The email is being sent to the last user listed in the table
//Passing `true` enables PHPMailer exceptions
//$mail = new PHPMailer(true);
$mail = new PHPMailer();
$body = file_get_contents('contents.html');
$mail->SMTPDebug = SMTP::DEBUG_SERVER;
$mail->isSMTP();
$mail->Host = '####';
$mail->SMTPAuth = true;
$mail->SMTPKeepAlive = true; //SMTP connection will not close after each email sent, reduces SMTP overhead
$mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
$mail->Port = 465;
$mail->Username = '###';
$mail->Password = '###';
$mail->setFrom('###', 'List manager');
$mail->addReplyTo('###', 'List manager');
$mail->Subject = 'PHPMailer Simple database mailing list test';
//Same body for all messages, so set this before the sending loop
//If you generate a different body for each recipient (e.g. you're using a templating system),
//set it inside the loop
$mail->msgHTML($body);
//msgHTML also sets AltBody, but if you want a custom one, set it afterwards
$mail->AltBody = 'To view the message, please use an HTML compatible email viewer!';
//Connect to the database and select the recipients from your mailing list that have not yet been sent to
//You'll need to alter this to match your database
$connection = mysqli_connect($server, $loginsql, $passsql, "database_name")
or die("Could not connect to database");
$result = mysqli_query($connection, 'SELECT user_login, user_email, db_prefix FROM userstest');
foreach ($result as $row) {
try {
$mail->addAddress($row['user_email'], $row['user_login']);
} catch (Exception $e) {
echo 'Invalid address skipped: ' . htmlspecialchars($row['user_email']) . '<br>';
continue;
}
try {
$mail->send();
echo 'Message sent to :' . htmlspecialchars($row['user_email']) . ' (' .
htmlspecialchars($row['user_email']) . ')<br>';
} catch (Exception $e) {
echo 'Mailer Error (' . htmlspecialchars($row['user_email']) . ') ' . $mail->ErrorInfo . '<br>';
//Reset the connection to abort sending this message
//The loop will continue trying to send to the rest of the list
$mail->getSMTPInstance()->reset();
}
//Clear all addresses and attachments for the next iteration
$mail->clearAddresses();
$mail->clearAttachments();
}
All - thanks for the help. I actually figured it out. The email address for setFrom was not the same as the account that was sending it out so it wouldn't work sending out to external domains.
I'd like to send mails via phpmailer and I'd like to get the name from the database for mail body with looping, but my code doesn't work. It keeps on getting the same name for every single mail. Here's my code:
<?php //Library require("phpmailer/classes/class.phpmailer.php");
//Database
$server = "localhost";
$username = "mydatabase_admin";
$password = "localadmin123";
$database = "mydatabase";
//Connect to database
$dbConnection = mysqli_connect($server, $username, $password, $database);
//Check connection
if ($dbConnection -> connect_error) {
echo "Connection Failed";
die ($dbConnection -> connect_error);
}
//Select database and data
$sql = "SELECT * FROM userdata";
$result = $dbConnection -> query($sql);
//Mailing
//Sender information
$mail = new PHPMailer();
$mail->SMTPDebug = 0;
//Use SMTP
$mail->IsSMTP();
$mail->SMTPAuth = true;
//SMTP Server
$mail->Host = "ssl://smtp.gmail.com";
$mail->Port = 465;
//SMTP Account
$mail->Username = "my_mail#gmail.com";
$mail->Password = "********";
//Automated Mail
$mail->SetFrom('tphp43598#gmail.com', 'Admin');
//Recipient info
if ($result->num_rows > 0) {
while ($row = $result->fetch_assoc())
{
$mail->AddAddress($row["Email"]);
$mail->Subject = "Product Review Reminder";
$mail->Body = "Hi ". $row["Full Name"] .",". "\n \nJust a reminder that you need to review the product coded ". $row["Product Handled"] . ".\n" . "Thank You";
}
}
//Output shown if(!$mail->Send()) {
echo 'Message was not sent.';
echo 'Mailer error: ' . $mail->ErrorInfo;
} else {
echo "\n" . 'Message has been sent.';
} ?>
if ($result->num_rows > 0) {
while ($row = $result->fetch_assoc())
{
$mail->AddAddress($row["Email"]);
$mail->Subject = "Product Review Reminder";
$mail->Body = "Hi ". $row["Full Name"] .",". "\n \nJust a reminder that you need to review the product coded ". $row["Product Handled"] . ".\n" . "Thank You";
if(!$mail->Send()) {
echo 'Message was not sent.';
echo 'Mailer error: ' . $mail->ErrorInfo;
} else {
echo "\n" . 'Message has been sent.';
}
}
}
You are calling sendmail() function outside while loop you are getting name variable whichever is last record. keep inside while loop.
Or if you need to track each individual mail send status then keep array of status. Keep pushing message into status array.
I have an array to be searched from numerous order_status_id
$order_status_id is pulled from a mysqli_query, which is working perfect for other conditional checks (in_array)
Below is the full code -
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
$con=mysqli_connect("localhost","abc_admin","abc123!","abc_store");//database connection
date_default_timezone_set("Asia/Kolkata");
$store_name_query = mysqli_query($con,"SELECT `value` FROM `oc_setting` WHERE `key`='config_name' AND `store_id`='0' AND `code`='config'");
$store_name_result = mysqli_fetch_array($store_name_query);
$store_name = $store_name_result['value'];
$date = date('Y-m-d');
$date_time = date('Y-m-d H:i:s');
$date_time_formatted = date("d M Y h:i:s A",strtotime($date_time));
$return_details = "SELECT * FROM `oc_return` WHERE `return_status_id`='1'";
if($return_data = mysqli_query($con,$return_details))
{
$count = mysqli_num_rows($return_data);
echo "<h1> $count Returns Processing</h1>";
require_once('PHPMailerAutoload.php');
while ($row=mysqli_fetch_array($return_data))
{
$return_id = $row['return_id'];
echo "Fetching Details for Return ID $return_id<br><br>";
$order_id = $row['order_id'];
$customer_id = $row['customer_id'];
$firstname = mb_convert_case($row['firstname'], MB_CASE_TITLE,"UTF-8");
$lastname = mb_convert_case($row['lastname'], MB_CASE_TITLE,"UTF-8");
$customer_name = $firstname." ".$lastname;
$email = $row['email'];
$product = $row['product'];
$comment = $row['comment'];
$return_date = $row['date_added'];
$date_added = date("d M Y",strtotime($row['date_added']));
$resolution_date = date('d-M-Y', strtotime($date_added. ' + 15 days'));
$resolution_date_in_format = date('Y-m-d H:i:s', strtotime($return_date. ' + 15 days'));
$mobile = $row['telephone'];
$return_reason_id = $row['return_reason_id'];
$order_date = $row['date_ordered'];
$order_details = mysqli_query($con,"SELECT * FROM `oc_order` WHERE `order_id`='$order_id'");
echo "Fetching Details for Order ID $order_id<br><br>";
while ($order_total = mysqli_fetch_array($order_details))
{
$total = str_replace(".0000","",$order_total['total']);
$order_status_id = $order_total['order_status_id'];
echo "$order_status_id<br><br>";
// CONDITIONAL CHECKS
$shipped_ud = "3 || 32";
$shipped_ud_status = explode(' || ',$shipped_ud);
$ready_process = "15 || 23 || 39";
$ready_process_status = explode(' || ',$ready_process);
$other_status_ids = "1 || 7 || 11 || 13 || 21 || 22 || 24 || 25 || 26 || 27 || 28 || 29 || 30 || 31 || 33 || 34 || 35 || 36 || 37 || 38 || 40";
$other_statuses = explode(' || ', $other_status_ids);
// IF ORDER IS IN PROCESSING STATE ↓ //
if($order_status_id == '2')
{
$cancel_comment = 'Order cancelled by Customer';
$cancel_order = mysqli_query($con,"UPDATE `oc_order` SET `order_status_id`='24' WHERE `order_id`='$order_id'");
$cancel_order_history = mysqli_query($con,"INSERT INTO `oc_order_history` (`order_id`,`order_status_id`,`notify`,`comment`,`date_added`) VALUES ('$order_id','24','1','$cancel_comment','$date_time')");
echo "Order has been cancelled<br><br>";
$update_return_table = mysqli_query($con,"UPDATE `oc_return` SET `return_status_id`='4',`return_action_id`='4' WHERE `return_id`='$return_id'");
$return_history_comment = "Your return request to cancel the order has been successfully processed. We are sorry to see you go away!";
$add_return_history = mysqli_query($con,"INSERT INTO `oc_return_history` (`return_id`, `return_status_id`, `notify`, `comment`, `date_added`) VALUES ('$return_id','4','1','$return_history_comment','$date_time')");
//Send Email to customer if order is in processing state //
$mail = new PHPMailer(true); // the true param means it will throw exceptions on errors, which we need to catch
$mail->IsSMTP(true); // telling the class to use SMTP
$mail->IsHTML(true);
$mail->CharSet = 'UTF-8';
try {
$mail->Host = "ssl://abcabc123.com"; // SMTP server
$mail->SMTPDebug = 0; // enables SMTP debug information (for testing)
$mail->SMTPAuth = true; // enable SMTP authentication
$mail->Host = "ssl://abcabc123.com"; // sets the SMTP server
$mail->Port = 465; // set the SMTP port for the GMAIL server
$mail->Username = "help#abcabc123.com"; // SMTP account username
$mail->Password = "Tmob134624!"; // SMTP account password
$mail->AddReplyTo('help#abcabc123.com', 'AbcAbc123');
$mail->AddAddress("$email", "$customer_name");
$mail->SetFrom('help#abcabc123.com', 'AbcAbc123');
$mail->addCustomHeader('In-Reply-To', "Order Return/Cancellation Request $return_id - Order ID $order_id");
$mail->XMailer = ' ';
$Subject = "Order Cancellation Request | Order ID $order_id";
$mail->Subject = "$Subject";
$mail->AltBody = 'To view the message, please use an HTML compatible email viewer!'; // optional - MsgHTML will create an alternate automatically
// Message //
$mail->Body = " \r\n";
// Body of Email trimmed
$mail->Send();
}
catch (phpmailerException $e) {
echo $e->errorMessage(); //Pretty error messages from PHPMailer
} catch (Exception $e) {
echo $e->getMessage(); //Boring error messages from anything else!
}
}
// IF ORDER IS SHIPPED OR IN TRANSIT ↓ //
else if(in_array($order_status_id,$shipped_ud_status))
{
$cancel_if_shipped = mysqli_query($con,"INSERT INTO `oc_order_history` (`order_id`,`order_status_id`,`notify`,`comment`,`date_added`) VALUES ('$order_id','24','1','Order Shipped, Cancellation Requested by Customer','$date_time')");
$update_return_for_shipped = mysqli_query($con,"UPDATE `oc_return` SET `return_status_id`='3',`return_action_id`='4' WHERE `return_id`='$return_id'");
//Email //
$mail = new PHPMailer(true); // the true param means it will throw exceptions on errors, which we need to catch
$mail->IsSMTP(true); // telling the class to use SMTP
$mail->IsHTML(true);
$mail->CharSet = 'UTF-8';
try {
$mail->Host = "ssl://abcabc123.com"; // SMTP server
$mail->SMTPDebug = 0; // enables SMTP debug information (for testing)
$mail->SMTPAuth = true; // enable SMTP authentication
$mail->Host = "ssl://abcabc123.com"; // sets the SMTP server
$mail->Port = 465; // set the SMTP port for the GMAIL server
$mail->Username = "help#abcabc123.com"; // SMTP account username
$mail->Password = "Tmob134624!"; // SMTP account password
$mail->AddReplyTo('help#abcabc123.com', 'AbcAbc123');
$mail->AddAddress("$email", "$customer_name");
$mail->SetFrom('help#abcabc123.com', 'AbcAbc123');
$mail->addCustomHeader('In-Reply-To', "Order Return - Order ID $order_id");
$mail->XMailer = ' ';
$Subject = "Return Request Update | Order ID $order_id";
$mail->Subject = "$Subject";
$mail->AltBody = 'To view the message, please use an HTML compatible email viewer!'; // optional - MsgHTML will create an alternate automatically
// Message //
$mail->Body = " \r\n";
// Body of Email trimmed
$mail->Send();
}
catch (phpmailerException $e) {
echo $e->errorMessage(); //Pretty error messages from PHPMailer
} catch (Exception $e) {
echo $e->getMessage(); //Boring error messages from anything else!
}
}
// IF ORDER IS PROCESSED OR IN READY TO SHIP STATE ↓
else if(in_array($order_status_id,$ready_process_status))
{
// SEND EMAIL TO CUSTOMER
//Email //
$mail = new PHPMailer(true); // the true param means it will throw exceptions on errors, which we need to catch
$mail->IsSMTP(true); // telling the class to use SMTP
$mail->IsHTML(true);
$mail->CharSet = 'UTF-8';
try {
$mail->Host = "ssl://abcabc123.com"; // SMTP server
$mail->SMTPDebug = 0; // enables SMTP debug information (for testing)
$mail->SMTPAuth = true; // enable SMTP authentication
$mail->Host = "ssl://abcabc123.com"; // sets the SMTP server
$mail->Port = 465; // set the SMTP port for the GMAIL server
$mail->Username = "info#abcabc123.com"; // SMTP account username
$mail->Password = "Tmob134624!"; // SMTP account password
$mail->AddReplyTo('info#abcabc123.com', 'AbcAbc123');
$mail->AddAddress($email, $customer_name);
$mail->SetFrom('info#abcabc123.com', 'AbcAbc123');
$mail->addCustomHeader('In-Reply-To', "Order Return Request ID $return_id - Order ID $order_id");
$mail->XMailer = ' ';
$Subject = "Return Request Update | Order ID $order_id";
$mail->Subject = "$Subject";
$mail->AltBody = 'To view the message, please use an HTML compatible email viewer!'; // optional - MsgHTML will create an alternate automatically
// Message //
$mail->Body = " \r\n";
// Body of Email trimmed
$mail->Send();
}
catch (phpmailerException $e) {
echo $e->errorMessage(); //Pretty error messages from PHPMailer
} catch (Exception $e) {
echo $e->getMessage(); //Boring error messages from anything else!
}
// Send SMS to Processing Team
// SMS Code //
$msg = "URGENT : ".$store_name."
Order ID ".$order_id."
Customer - ".$customer_name."
has been cancelled by Customer. Please DO NOT process this order.";
// $length= strlen($msg);
// $sms_count = ceil($length/160);
$sms_text = mysqli_real_escape_string($con,$msg);
$cc_mobile = '12456789';
////////////Promotion API Key 5y6zMwrqCEOs5oGJ6xyVZg //////////////////
$encode= rawurlencode($msg);
//request parameters array
$requestParams = array(
'channel' => '2',
'APIKey' => 'J8yAjtZkTUqMnDy6SDQN6Q',
'senderid' => 'ABCABC',
'Number' => $cc_mobile,
'Text' => $encode,
'DCS' => '0',
'Route' => '1',
'Flashsms' => '0',
);
//merge API url and parameters
$apiUrl = "https://login.smshub.com/api/mt/SendSMS?";
foreach($requestParams as $key => $val){
$apiUrl .= $key.'='.($val).'&';
}
$apiUrl = rtrim($apiUrl, "&");
//API call
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,$apiUrl);
curl_setopt($ch, CURLOPT_HEADER,0);
curl_setopt($ch,CURLOPT_POST,1);
curl_setopt($ch,CURLOPT_TIMEOUT,60);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER,0);
curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST,0);
curl_setopt($ch,CURLOPT_POSTFIELDS,0);
$data = curl_exec($ch);
if (curl_errno($ch) > 0) {
print 'There was a cURL error: ' . $curl_error($ch);
}
$json = json_decode($data);
$JobID = $json->{'JobId'};
curl_close($ch);
echo "Order Cancellation message sent to $cc_mobile <br><br>";
// End of SMS Code//
$cancel_if_processed = mysqli_query($con,"INSERT INTO `oc_order_history` (`order_id`,`order_status_id`,`notify`,`comment`,`date_added`) VALUES ('$order_id','24','1','Customer Requested Cancellation','$date_time')");
$cancel_if_processed = mysqli_query($con,"INSERT INTO `oc_order_history` (`order_id`,`order_status_id`,`notify`,`comment`,`date_added`) VALUES ('$order_id','24','1','Order Shipped, Cancellation Requested by Customer','$date_time')");
$update_return_for_processed = mysqli_query($con,"UPDATE `oc_return` SET `return_status_id`='13',`return_action_id`='4' WHERE `return_id`='$return_id'");
}
else if($order_status_id == '17')
{
$return_processing = mysqli_query($con,"UPDATE `oc_return` SET `return_status_id`='7' WHERE `return_id`='$return_id'");
echo "Return Status Updated to <strong>Processing</strong> for Return ID $return_id<br><br>";
$processing_comment = mysqli_real_escape_string($con,"<p><i>We are sorry that you are unsatisfied with your purchase from our store.</i></p><p>Your Return Request $return_id has been received and is being looked into by our Returns Processing Team.</p><p>We request you to please read our <a href='https://www.abcabc123.com/cancellation-and-refund' target='_blank' style='text-decoration:none;'>Cancellation & Return Policy</a></p><p>All decisions regarding Returns shall be final & binding as per our policy.<p><p>We shall update you latest by $resolution_date regarding your return as our minimum TAT is 15 days.<p>");
$return_history = mysqli_query($con,"INSERT INTO `oc_return_history`(`return_id`,`return_status_id`,`notify`,`comment`,`date_added`) VALUES ('$return_id','7','1','$processing_comment','$date_time')");
$resolution_comment = "Your return has been marked as Complete/Processed by our Returns Processing Team as the same does not meet our Cancellation and Returns policy for Refund or Replacement.";
$return_history_resolution = mysqli_query($con,"INSERT INTO `oc_return_history`(`return_id`,`return_status_id`,`notify`,`comment`,`date_added`) VALUES ('$return_id','3','0','$resolution_comment','$resolution_date_in_format')");
$cancel_if_delivered = mysqli_query($con,"INSERT INTO `oc_order_history` (`order_id`,`order_status_id`,`notify`,`comment`,`date_added`) VALUES ('$order_id','40','1','Order Delivered, Return Requested by Customer','$date_time')");
$update_order_for_delivered = mysqli_query($con,"UPDATE `oc_order` SET `order_status_id`='40' WHERE `order_id`='$order_id'");
$update_return_for_delivered = mysqli_query($con,"UPDATE `oc_return` SET `return_status_id`='7' WHERE `return_id`='$order_id'");
//Email Receiver//
$mail = new PHPMailer(true); // the true param means it will throw exceptions on errors, which we need to catch
$mail->IsSMTP(true); // telling the class to use SMTP
$mail->IsHTML(true);
$mail->CharSet = 'UTF-8';
try {
$mail->Host = "ssl://abcabc123.com"; // SMTP server
$mail->SMTPDebug = 0; // enables SMTP debug information (for testing)
$mail->SMTPAuth = true; // enable SMTP authentication
$mail->Host = "ssl://abcabc123.com"; // sets the SMTP server
$mail->Port = 465; // set the SMTP port for the GMAIL server
$mail->Username = "help#abcabc123.com"; // SMTP account username
$mail->Password = "Tmob134624!"; // SMTP account password
$mail->AddReplyTo('help#abcabc123.com', 'AbcAbc123');
$mail->AddAddress("$email", "$firstname $lastname");
$mail->SetFrom('help#abcabc123.com', 'AbcAbc123');
$mail->AddReplyTo('help#abcabc123.com', 'AbcAbc123');
$mail->addCustomHeader('In-Reply-To',"Return ID $return_id");
$mail->XMailer = ' ';
$mail->Subject = "Your Return Request ID $return_id is being processed";
$mail->AltBody = 'To view the message, please use an HTML compatible email viewer!'; // optional - MsgHTML will create an alternate automatically
$mail->Body = " \r\n ";
// Body of Email trimmed
$mail->Send();
} catch (phpmailerException $e) {
echo $e->errorMessage(); //Pretty error messages from PHPMailer
} catch (Exception $e) {
echo $e->getMessage(); //Boring error messages from anything else!
}
// EMAIL SENT ↑
}
// OTHER STATUSES
else if(in_array($order_status_id,$other_statuses))
{
echo "Checked positive for <span style='color:red;'>Other</span><br>";
$update_return_for_other = mysqli_query($con,"UPDATE `oc_return` SET `return_status_id`='3' WHERE `return_id`='$return_id'");
$return_history_for_other = mysqli_query($con,"INSERT INTO `oc_return_history`(`return_id`,`return_status_id`,`notify`,`comment`,`date_added`) VALUES ('$return_id','3','1','Return Invalid','$date_time')");
echo "Order not to be processed<br><br>";
}
// RETURNS UPDATED ↑
else
{
echo "Nothing to be processed <br><br>";
}
}
}
}
?>
$update_return_for_other mysqli_query works like charm for other checks being done before this check
My Code is processing other in_array checks which are small but, not this one!
Don't know what is the issue. Please help
I'm trying to use phpmailer to send out emails to each email address found in the database, but as a unique email. For some reason, it's sending duplicate emails, and it sends it out in as many copies as my query returns rows. So, if my query returns 5 rows, each recipient will receive 5 email (total emails sent is 25). I can't use the same email for multiple recipients because the email content is personalized.
What am I doing wrong with my code? Please help...
Here's my code:
$customers_query = "SELECT customer_name, customer_email, customer_id FROM customers";
$customers = mysql_query($customers_query);
if (!$customers) {
$message = 'Error notice: ' . mysql_error() . "\n";
$message .= 'Whole query: ' . $query;
die($message);
}
require_once('class.phpmailer.php');
// create an instance
while ($row = mysql_fetch_array($customers)) {
$email = $row['customer_email'];
$name = $row['customers_name'];
$id = $row['customer_id'];
$mail = new PHPMailer();
// use sendmail for the mailer
$mail->IsSendmail();
$mail->SingleTo = true;
$mail->IsHTML(true);
$mail->From = "noreply#domain.com";
$mail->FromName = "MyWebsite";
$mail->Subject = "Welcome to MyWebsite";
$mail->AddAddress($email);
$mail->Body = "Dear ".$name.", welcome to MyWebsite. Your ID is: ".$id.". Enjoy your stay.";
$mail->Send();
}
So, what am missing here? Why does it send that many emails?
Try this:
$mail->ClearAddresses(); after $mail->Send();
Try something like is below, you need to be counting your rows somehow so that it doesn't re-process them. Also, the AddAddress(); function is used to keep adding email addresses to the TO: field, so you need to call ClearAddresses(); in order to restart with a fresh set of recipients.
$customers_query = "SELECT customer_name, customer_email, customer_id FROM customers";
$customers = mysql_query($customers_query);
$count = mysql_num_rows($customers);
$result = mysql_fetch_array($customers);
$i = 0;
if (!$customers) {
$message = 'Error notice: ' . mysql_error() . "\n";
$message .= 'Whole query: ' . $query;
die($message);
}
require_once('class.phpmailer.php');
// create an instance
while ($i < $count) {
$email = mysql_result($result,$i,"customer_email");
$name = mysql_result($result,$i,"customers_name");
$id = mysql_result($result,$i,"customer_id");
$mail = new PHPMailer();
// use sendmail for the mailer
$mail->IsSendmail();
$mail->SingleTo = true;
$mail->IsHTML(true);
$mail->From = "noreply#domain.com";
$mail->FromName = "MyWebsite";
$mail->Subject = "Welcome to MyWebsite";
$mail->AddAddress($email);
$mail->Body = "Dear ".$name.", welcome to MyWebsite. Your ID is: ".$id.". Enjoy your stay.";
$mail->Send();
$mail->ClearAddresses();
$i++;
}
You can do one more thing, add one more extra field in the customer table, like is_email_sent, yes or no. Once sent email you can update specific row using primary key. so it will not send the same email to multiple time..