douhui1630 2017-05-10 21:19
浏览 433

PHP Mailer发送重复的电子邮件(一次发送两封电子邮件)

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']);
  • 写回答

2条回答 默认 最新

  • douyu4535 2017-05-10 21:57
    关注

    SingleTo with The SMTP Transport

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

    Plans on SingleTo in Future Versions of The PHPMailer

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

    Your Question

    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.

    PHP Log

    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.

    评论

报告相同问题?

悬赏问题

  • ¥500 火焰左右视图、视差(基于双目相机)
  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号
  • ¥15 基于单片机的靶位控制系统
  • ¥15 真我手机蓝牙传输进度消息被关闭了,怎么打开?(关键词-消息通知)
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本