PHPMailer best solution for looping through emails - php

I am trying to build a recall system in which users are sent reminder emails based on specified criteria. At the moment I would probably be sending 10-15 reminders at a time each week but it's possible that this may escalate to hundreds each week in the future. I've decided to use PHPMailer class to handle mail sending but I am very new to PHPMailer and so i'm not sure if the solution I have come up with will give the best performance or if my code can be improved. Also I am storing the date the email has been sent once it has been sent successfully.
This is what I have come up with:
<?php
//I have left out the database connection details for obvious reasons
require 'PHPMailer-master/PHPMailerAutoload.php';
$result = mysql_query("SELECT * FROM patients_test WHERE recall <> 0 AND DATE_ADD(`last_seen`, INTERVAL recall DAY) < DATE_ADD(NOW(), INTERVAL 21 DAY)");
while($row = mysql_fetch_array($result))
{
//Create new mail object
$mail = new PHPMailer;
///Mail settings
$mail->isSMTP(); // Set mailer to use SMTP
$mail->Host = 'host.co.uk'; // Specify main and backup SMTP servers
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = 'myusername'; // SMTP username
$mail->Password = 'mypassword'; // SMTP password
$mail->SMTPSecure = 'tls'; // Enable encryption, 'ssl' also accepted
$mail->From = 'myusername';
$mail->FromName = 'Mailer';
$mail->addReplyTo('replytoadd', 'Information');
$mail->WordWrap = 50; // Set word wrap to 50 characters
$mail->addAttachment('/var/tmp/file.tar.gz'); // Add attachments
$mail->isHTML(true); // Set email format to HTML
$mail->Subject = 'Reminder email';
$mail->Body = 'This is the HTML message body <b>in bold!</b>';
$mail->AltBody = 'This is the body in plain text for non-HTML mail clients';
//Recipient info
$ref = $row['identifier'];
$first_name = $row['first_name'];
$surname = $row['surname'];
$email = $row['email'];
$mail->addAddress($email, $first_name." ".$surname); // Add a recipient
if(!$mail->send())
{
echo 'Message could not be sent.';
echo 'Mailer Error: ' . $mail->ErrorInfo;
}
else
{
echo 'Reminder sent to '.$first_name.' '.$surname.' successfully<br/>';
mysql_query("UPDATE patients_test SET last_reminder= CURDATE() WHERE identifier='$ref'");//Update database to show that email has been sent
$mail->clearAllRecipients();
}
}
?>
Also the reason why I chose not to use PHPs default mail() function is because I am worried that my emails will be blocked as spam and I read somewhere that using something like PHPMailer can reduce the chances of this happening. Does anyone have any advice on this issue?
Thanks in advance
Rich

Fill the mail's headers can reduce this issue. The mail server have some rules which define if the mail is a spam or not. Moreover, sending mails through a loop may cause a blocking depending on how it is configured.

Related

How Sending multiple emails with PHPmailer

I have thousands of emails and I want to send an e-mail to all of them and I can not solve it. Is anyone able to help and clarify with examples in ways of solving
As shown in the following code what is the problem and what is the solution
$mail->isSMTP(); // Set mailer to use SMTP
$mail->Host = 'gator4164.hostgator.com '; // Specify main and backup SMTP servers
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = "..."; // SMTP username
$mail->Password = '...'; // SMTP password
$mail->SMTPSecure = 'ssl'; // Enable TLS encryption, `ssl` also accepted
$mail->Port = 465; // TCP port to connect to
$mail->CharSet = 'UTF-8';
$get = new get();
$getEmails = $get->getEmails();
$CountEmails = $get->CountEmails();
$mail->setFrom('email#gmail.com', 'Email Name');
foreach($getEmails as $getEmails){
for ($x = $emails['id']; $x <= $CountEmails; $x++) {
$mail->addAddress($emails['email'],$emails['name']);
$mail->isHTML(true); // Set email format to HTML
$mail->Subject = $title;
$mail->Body = nl2br($content);
$mail->AltBody = 'This is the body in plain text for non-HTML mail clients';
}
if(!$mail->send()) {
echo 'Message could not be sent.';
echo 'Mailer Error: ' . $mail->ErrorInfo;
} else {
echo'<div class="done">Done</div>';
}
}
For such kind of scenario, you have to create a Process Queue because every email sending needs some time to process and if the email count is thousand then in that case your system will crash as it is having a processing time limit. For creating a process queue you have to maintain a database table in which save all the records and maintain a status with different values like:
0: Initial, 1:Processing, 2: Email Sent
And create a separate functionality that pick a record on a regular interval and send the email and change the status. Put this functionality on CRON.
Don't add all of the recipients with "add" in one loop then you have one Email with all recipients. Send your E-Mail with every duration.
foreach($getEmails as $getEmails){
$emails['email'] = $getEmails['email'];
$emails['name'] = $getEmails['name'];
$mail->addAddress($emails['email'],$emails['name']);
$mail->isHTML(true); // Set email format to HTML
$mail->Subject = $title;
$mail->Body = nl2br($content);
$mail->AltBody = 'This is the body in plain text for non-HTML mail clients';
if(!$mail->send()) {
echo 'Message could not be sent.';
echo 'Mailer Error: ' . $mail->ErrorInfo;
} else {
echo'Email send to ' + $emails['email'];
}
$mail->clearAddresses();
}
something like this. So send the Email for every duration. To prevent that you send people duplicate emails you should set the status in your database if the email is send otherwise you send it again if you have an error in your script and you have to restart the script.

Is sending email from yahoo's email address possible using gmails's smtp in phpmailer

<?php
require ("PHPMailer-master/PHPMailerAutoload.php");
$mail = new PHPMailer;
if(isset($_POST['submit']))
{
$email_query = "select email1,email2 from tbl_contacts where id = '1'";
$query_result = mysql_query($email_query);
$value = mysql_fetch_array($query_result);
$primary_email = $value['email1'];
$CC = $value['email2'];
$name = $_POST['name'];
$email = $_POST['email'];
$subject = $_POST['subject'];
$message = $_POST['message'];
$mail->IsSendmail(); // Set mailer to use SMTP
$mail->Host = "smtp.google.com"; // Specify main and backup SMTP servers
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = $email; // SMTP username
//$mail->Password = 'password'; // SMTP password
$mail->SMTPSecure = 'ssl'; // Enable TLS encryption, `ssl` also accepted
$mail->Port = 465; // TCP port to connect to
$mail->setFrom($email, $name);
//$mail->addAddress('joe#example.net', 'Joe User'); // Add a recipient
$mail->addAddress($primary_email); // Name is optional
$mail->addReplyTo($email, '');
$mail->addCC($CC);
//$mail->addBCC('bcc#example.com');
//$mail->addAttachment('/var/tmp/file.tar.gz'); // Add attachments
//$mail->addAttachment('/tmp/image.jpg', 'new.jpg'); // Optional name
$mail->isHTML(true); // Set email format to HTML
$mail->Subject = $subject;
$mail->Body = $message;
$mail->AltBody = $message;
if(!$mail->send()) {
echo 'Message could not be sent.';
echo 'Mailer Error: ' . $mail->ErrorInfo;
} else {
echo 'Message has been sent';
redirect('/contact.php?message=Your+Message+Has+Been+Sent!', 'location');
}
}
?>
I am using gmail's smtp and it works fine if I send an email with a gmail account but when I send an email with an yahoo account it displays a success message but the message does not get delivered. Is it possible to send email from yahoo's email using gmail' smtp? If yes, how can I do it? And if not, how can I solve the problem?
In general,
avoid declaring incorrect identity.
This might be possible from technical aspect; however in 2016 most email systems tend to protect themself by using multip. techniques - like SPF, DKIM and DMARC and that is both for sending and evaluating received emails.
If this is true for more and more email systems and ESP's it's not hard to imagine what ESP giants like Yahoo, GMAIL and others are doing to express their hate on incorrectly declared identities (mark as spam, reject at SMTP handshake level, silently discard...).
In your case displaying success message only mean that your mail is received on MTA side for further processing, not anything about it's future.

How can I add a PHP script to Auto-respond with a "thank you" message

I'm php newbie that just figured out how to use php with phpmailer to send email addresses of my users to my email address to be added to a newsletter.
However, now I want to add a simple auto-respond script in php, so when users add their email to my guestlist it sends them an autoreply email to their email that says:
Thanks for signing up. [Picture of my logo] www.mysite.com
I've searched and searched, but I haven't been able to find a proper answer on how to create an autorespond script in php. Please let me know how I can accomplish this task. Thank you!
<?php
$email = $_REQUEST['email'] ;
require("C:/inetpub/mysite.com/PHPMailer/PHPMailerAutoload.php");
$mail = new PHPMailer();
// set mailer to use SMTP
$mail->IsSMTP();
$mail->Host = "smtp.comcast.net"; // specify main and backup server
$mail->SMTPAuth = true; // turn on SMTP authentication
$mail->Username = "myusername#comcast.net"; // SMTP username
$mail->Password = "*******"; // SMTP password
$mail->SMTPSecure = 'ssl'; // Enable TLS encryption, `ssl` also accepted
$mail->Port = 25;
$mail->From = $email;
// below we want to set the email address we will be sending our email to.
$mail->AddAddress("myemail#gmail.com", "Guestlist");
// set word wrap to 50 characters
$mail->WordWrap = 50;
// set email format to HTML
$mail->IsHTML(true);
$mail->Subject = "A new member wishes to be added";
$message = $_REQUEST['message'] ;
$mail->Body = $email;
$mail->AltBody = $email;
if(!$mail->Send())
{
echo "Message could not be sent. <p>";
echo "Mailer Error: " . $mail->ErrorInfo;
exit;
}
echo "Message has been sent";
$mail2 = new PHPMailer();
// set mailer to use SMTP
$mail2->IsSMTP();
$mail2->Host = "smtp.comcast.net"; // specify main and backup server
$mail2->SMTPAuth = true; // turn on SMTP authentication
$mail2->Username = "myusername#comcast.net"; // SMTP username
$mail2->Password = "*******"; // SMTP password
$mail2->SMTPSecure = 'ssl'; // Enable TLS encryption, `ssl` also accepted
$mail2->Port = 25;
$mail2->From = $email;
// below we want to set the email address we will be sending our email to.
$mail2->AddAddress("$email");
// set word wrap to 50 characters
$mail2->WordWrap = 50;
// set email format to HTML
$mail2->IsHTML(true);
$mail2->Subject = "Thank you for joining";
$message = "Please stay tune for updates" ;
$message = $_REQUEST['message'] ;
$mail2->Body = $message;
$mail2->AltBody = $message;
if(!$mail2->Send())
{
echo "Message could not be sent. <p>";
echo "Mailer Error: " . $mail2->ErrorInfo;
exit;
}
echo "Message has been sent";
?>
Update: 1
Ok, I figured out how to send auto-respond emails to users. However, now the users are receiving messages with their own email address and the name Root user
So what can I do to fix this problem so that users see my email address when they recevie auto-responses, and how can I make sure it says my name instead of root user?
Do not use the submitter's email address as the from address - it won't work as it looks like a forgery and will fail SPF checks. Put your own address as the From address, and add the submitter's address as a reply-to.
Using SMTPSecure = 'ssl' with Port = 25 is an extremely unusual combination, and very likely to be wrong. ssl/465 and tls/587 are more usual.
To send multiple messages, you do not need to create a second instance - just re-use the same one. You can reset any individual properties you want (such as Body) and clear addresses using $mail->clearAddresses(), then just call $mail->send() a second time.
It looks like you have based your code on an old example (try a new one) - make sure you are using latest PHPMailer - at least 5.2.10.
add:
echo "Message has been sent";
$mail = new PHPMailer();
$mail->From = 'myemail#gmail.com';
// below we want to set the email address we will be sending our email to.
$mail->AddAddress($email);
// set word wrap to 50 characters
$mail->WordWrap = 50;
// set email format to HTML
$mail->IsHTML(true);
$mail->Subject = "Thanks for joining ...";
$message = "Thanks for joining...";
$mail->Body = $email;
$mail->AltBody = $email;
$mail->Send();

PHPMailer: Mass Emails - Send all variable messages at once, instead of individually

i'm currently trying to figure out the best way to do this.
The current system i've made sends email one by one and fills in the information for each entry as in the array, such as email, first name and last name.
The problem here is if i send alot of messages it takes forever to run through as it's calling a function everytime, instead i want it to send them all at once through one single function.
I know you can add multiple to's but then the body of the email won't send the correct information relative to each email. If anyone can help me with this i'd really appreciate it, as i've searched all over for a solution.
<?php
require '../phpmailer/PHPMailerAutoload.php';?>
<?php
/* Block List */
$blocklist = array('emailblocked#gmail.com', 'emailblocked2#gmail.com');
$emaillist = array(
array(
'Email'=>'example#gmail.com',
'First Name'=>'John',
'Last Name'=>'Doe'
),
array(
'Email'=>'example2#gmail.com',
'First Name'=>'Joe',
'Last Name'=>'Doe'
),
array(
'Email'=>'example3#gmail.com',
'First Name'=>'Jane',
'Last Name'=>'Doe'
),
);
foreach($emaillist as $emailkey){
if (in_array($emailkey['Email'], $blocklist)) {
echo 'Message has been been blocked for '.$emailkey['Email'].'<br>';
}else{
$mail = new PHPMailer;
// $mail->SMTPDebug = 3; // Enable verbose debug output
$mail->isSMTP(); // Set mailer to use SMTP
$mail->Host = 'smtp.mandrillapp.com'; // Specify main and backup SMTP servers
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = 'username#example.com'; // SMTP username
$mail->Password = 'passwordgoeshere'; // SMTP password
$mail->SMTPSecure = 'tls'; // Enable TLS encryption, `ssl` also accepted
$mail->Port = 587; // TCP port to connect to
$mail->From = 'noreply#example.com';
$mail->FromName = 'Example';
$mail->addAddress($emailkey['Email'], $emailkey['First Name'].' '.$emailkey['Last Name']); // Add a recipient
$mail->addReplyTo('info#example.com', 'Information');
$mail->isHTML(true); // Set email format to HTML
$mail->Subject = $emailkey['First Name'].' '.$emailkey['Last Name'];
$emailtemp = file_get_contents('templates/temp-1.html');
$emailtempfilteremail = str_replace("[[email]]", $emailkey['Email'], $emailtemp);
$emailtempfilterfirstname = str_replace("[[firstname]]", $emailkey['First Name'], $emailtempfilteremail);
$emailtempfilterlastname = str_replace("[[lastname]]", $emailkey['Last Name'], $emailtempfilterfirstname);
$mail->Body = $emailtempfilterlastname;
$mail->AltBody = 'This is a spicy email!';
if(!$mail->send()) {
echo 'Message could not be sent.';
echo 'Mailer Error: ' . $mail->ErrorInfo;
} else {
echo 'Message has been sent to '.$emailkey['Email'].'<br>';
}
$mail->ClearAllRecipients();
}
}
?>
Thank you
There's an example of how to send to a list from a database efficiently in the examples bundled with PHPMailer. There's nothing inherently likely to get you blacklisted by using PHPMailer for sending large volumes, but you do need to tread carefully. Mandrill isn't magic - it's as vulnerable as anything else to being blocked if you send spam through it.
If you want to send 50 simultaneously from PHP, fire up multiple processes with the pcntl extension, but it won't actually help you very much as you'll be increasing overhead enormously. You can set SMTPKeepAlive = true in PHPMailer which will reduce overhead a lot (it avoids making a new connection for every message), but it still won't send simultaneous messages - nothing will. There isn't an option in SMTP to send multiple messages with different bodies simultaneously on the same connection.
Sending to a big list during a page load in a browser is very unreliable; use a cron script or background process to do your actual sending and just set it up through your web interface. One tip if you are waiting for a page load - call ignore_user_abort() early on so that it won't stop sending if your browser closes the connection - and beware the page refresh! If you want to send much faster, install a local mail server like postfix and use that to relay - it will be far faster and more reliable than sending directly.
Yes, it is possible with a modification of your code, the problem is not with the PHPMailer itself, but with your approach. You should avoid using an new instance of the class inside a loop (this leads to memory exhaustion with large lists), instead, only invoke $mail->addAddress(...) or $mail->Subject(...) inside the foreach loop.
If you read the source code of the PHPMailer, you will notice how exactly the functions addAddress(), Subject() or Body() works.
Your code should look something like this:
<?php
/*Move your "generic" initialization outside the loop*/
$mail = new PHPMailer;
// $mail->SMTPDebug = 3; // Enable verbose debug output
$mail->isSMTP(); // Set mailer to use SMTP
$mail->Host = 'smtp.mandrillapp.com'; // Specify main and backup SMTP servers
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = 'username#example.com'; // SMTP username
$mail->Password = 'passwordgoeshere'; // SMTP password
$mail->SMTPSecure = 'tls'; // Enable TLS encryption, `ssl` also accepted
$mail->Port = 587; // TCP port to connect to
$mail->From = 'noreply#example.com';
$mail->FromName = 'Bet Monkey';
$mail->isHTML(true); // Set email format to HTML
$mail->addReplyTo('info#example.com', 'Information');
$emailtemp = file_get_contents('templates/temp-1.html');
$mail->AltBody = 'This is a spicy email!';
/*Start the loop by adding email addresses*/
foreach($emaillist as $emailkey){
if (in_array($emailkey['Email'], $blocklist)) {
echo 'Message has been been blocked for '.$emailkey['Email'].'<br>';
}else{
$mail->addAddress($emailkey['Email'], $emailkey['First Name'].' '.$emailkey['Last Name']); // Add a recipient
$mail->Subject = $emailkey['First Name'].' '.$emailkey['Last Name'];
$emailtempfilteremail = str_replace("[[email]]", $emailkey['Email'], $emailtemp);
$emailtempfilterfirstname = str_replace("[[firstname]]", $emailkey['First Name'], $emailtempfilteremail);
$emailtempfilterlastname = str_replace("[[lastname]]", $emailkey['Last Name'], $emailtempfilterfirstname);
$mail->Body = $emailtempfilterlastname;
if(!$mail->send()) {
echo 'Message could not be sent.';
echo 'Mailer Error: ' . $mail->ErrorInfo;
} else {
echo 'Message has been sent to '.$emailkey['Email'].'<br>';
}
$mail->ClearAllRecipients();
}
}
Using the above approach I personally have send hundreds of thousands emails, but, as they say in the comments - you'll risking to be blacklisted (you can check here or here for details).

i am submitting my form with php but it is going to spam

**> the mail posted with the below given is going to spam. I am not using
captcha in the form as i don want to. So can anybody help me to the
mail in Inbox**
<?php
if(isset($_POST['submit']))
{
$name = $_POST['Name'];
$email = $_POST['email'];
$phone = $_POST['phone'];
$date = $_POST['checkinDate'];
$package = $_POST['package'];
$person = $_POST['adults'];
$kids = $_POST['kids'];
$ip=$_SERVER['REMOTE_ADDR']; //trace the ip address of the user submited
$subject ="Query From :Kerala-Honeymoon-Packages - Promotion\n"; //subject of the email
$to="paul#roverholidays.com";
$cc="online#roverholidays.com";
$ccc="deepti#roverholidays.com";
$from=$_POST['email'];
$adc="Name :$name\n";
$adc.="Email :$email\n";
$adc.="Phone :$phone\n";
$adc.="Date of Travel :$date\n";
$adc.="Package :$package\n";
$adc.="Adults :$person\n";
$adc.="Kids :$kids\n";
$message ="$name copy of the query you submited in Kerala-Honeymoon-Packages";//message header to user submited
$headers="From: <".$from. ">" ;
mail($cc,$subject,$adc,$headers);
mail($ccc,$subject,$adc,$headers);
mail($email,$message,$adc);
header("Location: thanks.htm");
}
else
{
return false;
}
?>
coding-wise I don't think there is anything you can do because it is the email server that classifies your email as a spam not the way you coded your script. All you can do is to control it from the receiver email setting i.e you setup your gmail filters to detect that email based on keyword like "Kerala-Honeymoon-Packages" and move it out of spam.
I don't know for sure what the email servers algorithms are for marking email as spam. However, I think sending email from different domain rather than your domain name is likely to be detected as phishing email. what I mean is when someone put his/her yahoo email in the form and click on send, your server will send the email to emails addresses in the script but it will send it as if it came from yahoo, which will be suspicious for the receiver email server as it knows that it did not come from yahoo.
Many email services block mail sent directly from random servers because they have little to no reputation as a legitimate source of non-spam emails. Instead of using the straight php mail() function, try using a SMTP service like Mandrill or Gmail's SMTP service. Both are free.
Here is the configuration page for Mandrill:
http://help.mandrill.com/entries/23737696-How-do-I-send-with-PHPMailer-
<?php
require 'class.phpmailer.php';
$mail = new PHPMailer;
$mail->IsSMTP(); // Set mailer to use SMTP
$mail->Host = 'smtp.mandrillapp.com'; // Specify main and backup server
$mail->Port = 587; // Set the SMTP port
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = 'MANDRILL_USERNAME'; // SMTP username
$mail->Password = 'MANDRILL_APIKEY'; // SMTP password
$mail->SMTPSecure = 'tls'; // Enable encryption, 'ssl' also accepted
$mail->From = 'from#example.com';
$mail->FromName = 'Your From name';
$mail->AddAddress('josh#example.net', 'Josh Adams'); // Add a recipient
$mail->AddAddress('ellen#example.com'); // Name is optional
$mail->IsHTML(true); // Set email format to HTML
$mail->Subject = 'Here is the subject';
$mail->Body = 'This is the HTML message body <strong>in bold!</strong>';
$mail->AltBody = 'This is the body in plain text for non-HTML mail clients';
if(!$mail->Send()) {
echo 'Message could not be sent.';
echo 'Mailer Error: ' . $mail->ErrorInfo;
exit;
}
echo 'Message has been sent';

Categories