PHPMailer slow response time - php

I'm using PHPMailer to send a forgot password email to users and when the user submits their email to the code below the page takes a few minutes to load!! Im not expecting the email to be send instantly but is there a way to make it so it will redirect the user while still sending the email?
I'm fairly new to php so there could be something simple I'm missing out.
Here is my code:
<?php
define('DB_NAME', '#######');
define('DB_USER', '#######');
define('DB_PASSWORD', '#######');
define('DB_HOST', 'localhost');
$conn = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
if (!$conn) {
die('Could not connect: ' . mysqli_connect_error());
}
$recovery = $_POST['recovery'];
$sql = "SELECT forgotpass FROM members WHERE username = '$recovery'";
$result=mysqli_query($conn, $sql);
while($row = mysqli_fetch_array($result, MYSQLI_ASSOC))
{
echo "Please wait... ";
$mailto = $recovery;
$mailSub = "Here's your password!";
$mailMsg = $row['forgotpass'];
require 'PHPMailer-master/PHPMailerAutoload.php';
$mail = new PHPMailer();
$mail ->IsSmtp();
$mail ->SMTPDebug = 0;
$mail ->SMTPAuth = true;
$mail ->SMTPSecure = 'ssl';
$mail ->Host = "bemoresocial.co.uk";
$mail ->Port = 465; // or 587
$mail ->IsHTML(true);
$mail ->Username = "info#bemoresocial.co.uk";
$mail ->Password = "#########";
$mail ->SetFrom("info#bemoresocial.co.uk");
$mail ->Subject = $mailSub;
$mail ->Body = $mailMsg;
$mail ->AddAddress($mailto);
if(!$mail->Send())
{
echo "Something went wrong :(";
}
else
{
header('Location: ./success.php');
}
}
mysqli_close($conn);

SMTP can be slow, often deliberately so; it's really not well suited to sending email to remote servers during page submission processing, as PHP is typically used for.
The best way to fix this is to install a local mail server such as Postfix. Submitting messages to that (using SMTP to localhost) will be very fast, and then the mail server can deal with the slower onward delivery. This is effectively a queuing system, but is much easier than using something like beanstalkd, redis, or rabbitmq to build your own queue.
In your code, the require inside the while loop will cause a fatal error if it goes round more than once, because you will be requiring the same class file repeatedly. To send to multiple recipients efficiently, reuse the PHPMailer instance - you don't need to start from scratch every time around the loop - if you can use keepalive, this will also be much faster - see the mailing list example provided with PHPMailer for how to do that.
Though it's not part of the problem you're seeing, I can see you've based your code on an obsolete example, and you're using an old version of PHPMailer - upgrade to 6.0.

I ran into the same problem with VERY SLOW running PHP Mailer, like 3 minutes to send 15 emails using the Website Host SMTP server.
What I did to make it finish within seconds is to switch to gmail smtp. When you do this you'll need to go to Google and generate an app password Sign In Using App Password. So in your code use your normal email address with the generated password (note your normal password still works for your normal email access) and use tls security.
When I moved the program from testing to production the email failed. I found I had to go to google and just sign in and everything worked again.
Also note if you turn on SMTPDebug = 2; it will show you each step and the time it finished.
include ('class.PHPMailer.php');
$mail = new PHPMailer(true); // Passing `true` enables exceptions
try {
//Server settings
$mail->SMTPDebug = 0; // 0=no output, 1=Commands, 2=Data & Commands, 3=2+connection status 4=Low-Level data output
$mail->isSMTP(); // Set mailer to use SMTP
$mail->Host = 'smtp.gmail.com'; // Specify main and backup SMTP servers
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = 'mickeymouse#gmail.com'; // SMTP username
$mail->Password = 'aaaabbbbccccdddd'; // SMTP password (used google Generated app password)
$mail->SMTPSecure = 'tls'; // Enable TLS encryption, `ssl` also accepted
$mail->Port = 587; // TCP port to connect to
// Recipients
$i = 0; $address="";
foreach($recipients as $i => $address)
{
$mail->addAddress($address);
}
$mail->addReplyTo('mickeymouse#gmail.com', 'Mickey');
$mail->isHTML(true);
$mail->setFrom('mickeymouse#gmail.com', 'Mickey');// Set email format to HTML
$mail->Subject = $subject;
$mail->Body = $body;
$mail->send();
$message = 'Message has been sent';
}
catch (Exception $e) {
$message = 'Message could not be sent.'."<br>".
'Mailer Error: ' . $mail->ErrorInfo;
}

Related

Setup PHPMailer in a linux server GoDaddy

I extracted the PHPMailer zip in my server root and created the contact.php file to handle the contact form data but when i submit the form i get an error not one i used in my catch block get this error Oops! An error occured and your message could not be sent. i, need some help setting up the PHPMailerin my server. Here's my contact.php code
<?php
use PHPHMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require 'PHPMailer/src/Exception.php';
require 'PHPMailer/src/PHPMailer.php';
require 'PHPMailer/src/SMTP.php';
$mail = new PHPMailer(true);
try {
//
$mail->SMTPDebug = 0;
$mail->isSMTP();
$mail->Host = 'sxb1plzcpnl473190.prod.sxb1.secureserver.net';
$mail->SMTPAuth = true;
$mail->Username = 'info#***.co.za';
$mail->Password = '***';
$mail->SMTPSECURE = 'tls';
$mail->Port = 587;
// receipt
$mail->setFrom('My Mail');
$mail->addAddress($_POST['email']);
// content
$mail->isHtml(true);
$mail->Name = $_POST['name'];
$mail->Phone = $_POST['phone'];
$mail->Email = $_POST['email'];
$mail->Subject = $_POST['subject'];
$mail->Body = $_POST['message'];
$mail->send();
// echo message has been sent
// header('Location: www.***.co.za');
echo 'alert("Thank You For Contacting US, Will Get Back To You Within 24Hours")';
exit();
} catch (Exception $e) {
echo 'Failed To Send Contact Info, Please Try Again';
}
?>
GoDaddy imposes very strict (to the point of becoming almost useless) constraints on sending an email. They block outbound SMTP to ports 25, 465 and 587 to all servers except their own. This problem is the subject of many frustrating questions on Stack Overflow. The solution is extremely poorly documented by GoDaddy: you must send through their servers, and also disable all security features, username, and password (great, huh?!), giving you this config for PHPMailer:
$mail->isSMTP();
$mail->Host = 'localhost';
$mail->SMTPAuth = false;
$mail->SMTPAutoTLS = false;
$mail->Port = 25;
GoDaddy also refuses to send with a From address belonging to any aol, gmail, yahoo, hotmail, live, aim, or msn domain (see their docs). This is because all those domains deploy SPF and DKIM anti-forgery measures, and faking your from address is forgery.
For more details:
https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting#godaddy

PHPMailer stops after 1st or 2nd e-mail in my for loop

I'm using PHPMailer 5.2 (https://github.com/PHPMailer/PHPMailer/tree/5.2-stable) in my localhost (XAMPP 3.2.2) and I have the following issue:
I want to send 1 e-mail to a lot of people (the message is slightly different for each one of them). So I created a for to go through all theses people's e-mails in an array, sending 1 e-mail to each of those addresses. The URL that I enter in my browser to run the send-emails.php is like http://localhost/mailer/send-emails.php, but soon after the 1st e-mail is sent, the webpage stops loading and nothing more happens (no log error, no exception, no console log, no nothing...). Sometimes, if I'm lucky, the localhost can send 2 e-mails from the array, but then it stops.
I don't know why the PHPMailer is stopping after the 1st or the 2nd e-mail are sent (in the example code bellow, it would only send to aaaa#gmail.com and, maybe, to bbb#gmail.com).
Can someone help?
The code is:
<?php
ini_set('MAX_EXECUTION_TIME', 3600);
include('PHPMailerAutoload.php');
$mail = new PHPMailer();
$mail->isSMTP();
$mail->CharSet = 'UTF-8';
$mail->Host = 'smtp.office365.com';
$mail->Port = 587;
$mail->SMTPSecure = 'STARTTLS';
$mail->SMTPAuth = true;
$mail->Username = "xxxx#xxxx"; //my e-mail
$mail->Password = "xxx"; //my password
$mail->setFrom("xxxx#xxxx", "Xxxx");
//'To' addresses
$email = array("aaaa#gmail.com","bbb#gmail.com","cccc#gmail.com","dddd#gmail.com","eeee#gmail.com");
for ($i=0; $i < sizeof($email); $i++) {
try {
$mail->addAddress($email[$i]);
//Blind copy to myself
$mail->AddBCC("xxxx#xxxx", "Xxxx");
$mail->Subject = "...";
$mensagemHtml = "...";
$mensagemBody = "...";
$mail->msgHTML("<html>{$mensagemHtml}</html>");
$mail->AltBody = "{$mensagemBody}";
$mail->send();
$mail->clearAddresses();
} catch (Exception $e) {
echo 'Error: ' . $mail->ErrorInfo;
}
}

PHPMailer - Could not authenticate

I've been running PHPMailer for a year now on a php server. Everything was fine until 3 days ago when I started getting the following error:
SMTP Error: Could not authenticate.
Allow less secure apps is ON
Here is the code:
function SendEmail($to,$cc,$bcc,$subject,$body) {
require 'PHPMailerAutoload.php';
$mail = new PHPMailer(true);
$mail->SMTPDebug = 1;
try {
$addresses = explode(',', $to);
foreach ($addresses as $address) {
$mail->AddAddress($address);
}
if($cc!=''){
$mail->addCustomHeader("CC: " . $cc);
}
if($bcc!=''){
$mail->addCustomHeader("BCC: " . $bcc);
}
$mail->IsSMTP();
$mail->SMTPAuth = true; // turn on SMTP authentication
$mail->SMTPSecure = "tls"; // sets the prefix to the servier
$mail->Host = "smtp.gmail.com"; // sets GMAIL as the SMTP server
$mail->Port = 587;
$mail->Username = "myemail#gmail.com"; // SMTP username
$mail->Password = "myemailpass"; // SMTP password
$webmaster_email = "myemail#gmail.com"; //Reply to this email ID
$name=$email;
$mail->From = $webmaster_email;
$mail->FromName = "Service";
//$mail->AddReplyTo($webmaster_email, "DiFractal Customer Service");
$mail->WordWrap = 50; // set word wrap
$mail->IsHTML(true); // send as HTML
$mail->Subject = $subject;
$mail->Body = $body;
return $mail->Send();
} catch (phpmailerException $e) {
$myfile = fopen("debug_email.txt", "w");
fwrite($myfile,$e->errorMessage() . "\n" . $mail->ErrorInfo);
fclose($myfile);//Pretty error messages from PHPMailer
} catch (Exception $e) {
$myfile = fopen("debug_email_stp.txt", "w");
fwrite($myfile,$e->getMessage());
fclose($myfile);//Pretty error messages from PHPMailer
}
}
Note I just updated PHPMailer to the latest version to try to remedy the problem but nothing has changed! The old version 5.2.2 was still having the same problem!
EDIT: I just had one successful email go through to google and sent properly. Which now makes me question if it's lag issue or something of that sort. Does anyone know how phpmailer functions under high loads or if high loads can cause the above error?
Try going to:
myaccount.google.com -> "connected apps & sites", and turn "Allow less secure apps" to "ON".
Alternative:
Try changing SMTP Port to: 465 (gmail also).
I was having similar issues and needed to set the from address
$mail->setFrom('myemail#gmail.com', 'Webmaster');
Make sure you check google's usage limits! PHPMailer will not tell you particulars it will just give you the Could not authenticate error but the reason why can be because of your limits.
# https://support.google.com/a/answer/166852?hl=en
Upgraded to a new account with google business and switched to that account. Issue resolved.

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).

PHP Mailer - Internal Server Error

I have been trying to make the contact form on my website to work and I've spent weeks trying to figure it out and I couldn't.
Here's the problem - I purchased a web template and it came with the PHPMailer. I'm now done plugging my content into the template, but the contact form has been a pain. I've followed the instructions the best I know on the PHP file, but it's giving me an "Internal Server Error" when I am testing the contact form.
Here's the code that came with my purchase:
$name = trim($_POST['name']);
$email = $_POST['email'];
$subject = $_POST['subject'];
$message = $_POST['message'];
$site_owners_email = 'name#mydomain.com'; // Replace this with your own email address
$site_owners_name = 'My Name'; // Replace with your name
try {
require_once('/Beta-BRC/php/PHPMailer/class.phpmailer.php');
$mail = new PHPMailer();
$mail->CharSet = 'UTF-8';
$mail->From = $email;
$mail->FromName = $name;
$mail->Subject = "[WEB Form] ".$subject;
$mail->AddAddress($site_owners_email, $site_owners_name);
$mail->Body = $message;
$mail->Mailer = "smtp";
$mail->Host = "smtp.gmail.com"; // Replace with your SMTP server address
$mail->Port = 465;
$mail->SMTPSecure = "SSL";
$mail->SMTPAuth = true; // Turn on SMTP authentication
$mail->Username = "name#mydomain.com"; // SMTP username
$mail->Password = "mypassword"; // SMTP password
//echo "true";
if($mail->Send()) {
echo "true";
} else {
echo "Error sending: " . $mail->ErrorInfo;
}
} catch (Exception $e) {
echo $e;
}
Quick note - I've alrealy tried using a GMAIL account on this part but it still does not work.
$mail->Username = "name#mydomain.com"; // SMTP username
$mail->Password = "mypassword"; // SMTP password
There's no need to log into Gmail with phpmailer. Below is an example of my phpmailer function using the default settings.
public function sendEmail($toaddress,$toname,$subject,$message){
if($template = file_get_contents('/home/username/domains/mydomain.com/public_html/html/email-template.html')){
$template = str_replace("[SUBJECT]",$subject,$template);
$template = str_replace("[CONTENT]",nl2br($message),$template);
$mailer = new PHPMailer;
$mailer->XMailer = "Organization Name 4.0.0";
if($this->is_logged_in()){
$mailer->AddCustomHeader("X-Originating-User-ID",$this->acct['id']);
}
$mailer->AddCustomHeader("X-Originating-IP",$_SERVER['REMOTE_ADDR']);
$mailer->setFrom("outbound#mydomain.com","From Name");
$mailer->AddAddress($toaddress,$toname);
$mailer->Subject = $subject;
$mailer->MsgHTML($template);
$mailer->AltBody = $message;
return $mailer->Send();
}else{
return false;
}
}
The email address listed doesn't actually exist. The email is just being sent from my server and phpmailer just says it's from that email address.
Try modifying my function to suit your needs and let me know how that works.
Note: You'll need to make sure your mail server is turned on for this to work
Although you don't have to use my function at all. Try debugging your code by checking some error logs on your server. Typically in the apache error logs (if you're running apache, however). Checking error logs is a huge part of troubleshooting your code and often can help you become more proactive.
I hope this helps even the slightest!
The specific cause of the Internal Server Error is the incorrect path you've supplied to the require_once statement that loads the PHPMailer class.
The path you've supplied is /Beta-BRC/php/PHPMailer/class.phpmailer.php, where the correct statement should be
require_once('/home/trsta/public_html/Beta-BRC/php/PHPMailer/class.phpmailer.php');
or perhaps more generally:
require_once($_SERVER['DOCUMENT_ROOT'].'/home/trsta/public_html/Beta-BRC/php/PHPMailer/class.phpmailer.php');
You've provided effectively a URL, but PHP requires the path in the server file system, which is not the same.
That should get you past this error. It's possible that there are others.

Categories