PHP mailer is sending two emails at once i tried to send it without loop just a single email but it was the same result
I found this here on stackoverflow but not changing anything
$mail->SingleTo = true;
So what can i do for this how can i send only one email per recipient ?
Here is my custom Mailer class
class Mailer
{
public static function sendMail($subject, $msgWithHtml, $msgNotHtml, array $recipients, array $attachmentPath = null )
{
$mail = new \PHPMailer;
//$mail->SMTPDebug = 3; // Enable verbose debug output
$mail->isSMTP(); // Set mailer to use SMTP
$mail->Host = 'mail.lotfio-lakehal.com'; // Specify main and backup SMTP servers
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = 'noreplay@lotfio-lakehal.com'; // SMTP username
$mail->Password = '------------'; // SMTP password
$mail->SMTPSecure = 'ssl'; // Enable TLS encryption, `ssl` also accepted
$mail->Port = 465; // TCP port to connect to
$mail->setFrom('noreplay@lotfio-lakehal.com');
foreach($recipients as $email)
{
$mail->addAddress($email); // Add a recipient // Name is optional
}
$mail->SingleTo = true; //will send mail to each email address individually
$mail->addReplyTo('contact@lotfio-lakehal.com', 'Information');
if($attachmentPath){
foreach($attachmentPath as $file)
{
$mail->addAttachment($file);
}
}
$mail->isHTML(true); // Set email format to HTML
$mail->Subject = $subject;
$mail->Body = $msgWithHtml;
$mail->AltBody = $msgNotHtml;
return $mail->send();
}
}
and here is how iam calling this method
use fordev\app\helpers\Mailer;
Mailer::sendMail('Email test from mailer', '<div></div>', 'qdqsdq dqsdqsdqsd', ['lotfiolakehal@gmail.com','contact@lotfio-lakehal.com']);
The SingleTo is only supported in "mail" and "sendmail" transports, not in "SMTP".
Since you use the "SMTP" transport, The SingleTo won't work. The authors of the PHPMailer class should have thrown an exception to exclude cases like that when when the SingleTo is not actually honored. If you use the SMTP transport, just loop the send for each address one-by-one (just call $mail->addAddress one time to pass just one address for each instance of the PHPMailer class), and don't touch the SingleTo property value, keep it default (false).
SingleTo is planned to be deprecated in the release of PHPMailer 6.0, and removed in 7.0. The authors of PHPMailer expalained that it's better to control sending to multiple recipients at a higher level:
PHPMailer isn't a mailing list sender.
Source: https://github.com/PHPMailer/PHPMailer/issues/1042
Use of the PHP mail() function needs to be discouraged because it's extremely difficult to use safely; SMTP is faster, safer, and gives more control and feedback."
The question was "So what can i do for this how can i send only one email per recipient?"
Just modify the arguments of the sendMail and change it from "array $recipients" to just a single $recipient, so it will the this:
public static function sendMail($subject, $msgWithHtml, $msgNotHtml, $recipient, array $attachmentPath = null )
And replace the following code
foreach($recipients as $email)
{
$mail->addAddress($email); // Add a recipient // Name is optional
}
to
$mail->addAddress($recipient);
If you cannot modify the declaration of the sendMail function since it's alreay used by other code, keep it, but move all its code to another function:
public static function sendMailSingleRecipient($subject, $msgWithHtml, $msgNotHtml, $recipient, array $attachmentPath = null )
so the code of the function sendMail will be like that:
foreach($recipients as $email)
{
self::sendMailSingleRecipient($subject, $msgWithHtml, $msgNotHtml, $email, $attachmentPath)
}
The whole code will be the following:
class Mailer
{
public static function sendMailSingleRecipient($subject, $msgWithHtml, $msgNotHtml, $recipient, array $attachmentPath = null )
{
$mail = new \PHPMailer;
//$mail->SMTPDebug = 3; // Enable verbose debug output
$mail->isSMTP(); // Set mailer to use SMTP
$mail->Host = 'mail.lotfio-lakehal.com'; // Specify main and backup SMTP servers
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = 'noreplay@lotfio-lakehal.com'; // SMTP username
$mail->Password = '------------'; // SMTP password
$mail->SMTPSecure = 'ssl'; // Enable TLS encryption, `ssl` also accepted
$mail->Port = 465; // TCP port to connect to
$mail->setFrom('noreplay@lotfio-lakehal.com');
$mail->addAddress($recipient); // Add a recipient // Name is optional
$mail->addReplyTo('contact@lotfio-lakehal.com', 'Information');
if($attachmentPath){
foreach($attachmentPath as $file)
{
$mail->addAttachment($file);
}
}
$mail->isHTML(true); // Set email format to HTML
$mail->Subject = $subject;
$mail->Body = $msgWithHtml;
$mail->AltBody = $msgNotHtml;
return $mail->send();
}
public static function sendMail($subject, $msgWithHtml, $msgNotHtml, array $recipients, array $attachmentPath = null )
{
foreach($recipients as $email)
{
self::sendMailSingleRecipient($subject, $msgWithHtml, $msgNotHtml, $email, $attachmentPath)
}
}
}
If you still don't like that the sendMail function loops for each of the addresses, but you need to use the smtp transport (not sendmail and not mail) don't use the \PHPMailer class from that third-party library hosted at GitHub and implement the smtp transport by yourself. You will anyway have to send each message separately to the SMTP server over the TCP/IP connection, but each message will have only one "To:" recipient and the messages would not duplicate.
If you suspect that the existing code is still but the function is called twice, just add logging capabilities to your code and check how many times it has been called. If you can see php error log, just add the error_log() to the beginning of the function, e.g.
error_log(print_r($recipients, true));
or
error_log(implode(',', $recipients));
So you will see from the log how many times the function have been actually called. Just don't forget to remove the error_log line from your code. If you don't have access to the error log file, use file_put_contents:
file_put_contents($filepath, implode(',', $recipients).PHP_EOL, FILE_APPEND);
Before calling it, set $filepath to the path name of the file to which you have access.
I had the same problem. This happens if you call $mail->Send()
twice.
Delete the send
function of your PHPmailer config file, and add an if
statement at the end of your instruction:
include ("../PHPMailer/sendEmail.php");
if($mail->Send()) {
echo "ok";
} else {
echo "fail";
}