PHP邮件服务将循环邮件发送给每个人。怎么避免呢?

问题描述 投票:0回答:2

对于我的网页,我有一个PHP邮件服务,让我通过发送邮件

EmailService::getService()->sendEmail($email, $first_name, $subject, $body);

除非我将此行放入循环中,例如通知所有列出的管理员,否则这样可以正常工作:

$sql = "SELECT * FROM admin_notifications";
$result = mysqli_query($con, $sql);
while($row = mysqli_fetch_assoc($result)){      
    EmailService::getService()->sendEmail($row['email'], $row['first_name'], $subject, $body);
}

现在每位管理员都收到每封邮件。例如,如果有3个管理员,则每个管理员收到3个不同的邮件。该服务似乎每个发送3个邮件到每个接收器。

由于我没有实现邮件服务本身,因为我不完全理解它,我真的不知道从哪里开始寻找这个bug。

也许这里有人有建议吗?

这是邮件服务的代码:

<?php

    /*Verschickt Emails*/
    use TijsVerkoyen\CssToInlineStyles\CssToInlineStyles;

    use PHPMailer\PHPMailer\PHPMailer;
    use PHPMailer\PHPMailer\Exception;

    class EmailService{
        /**
        * instance
        *
        * Statische Variable, um die aktuelle (einzige!) Instanz dieser Klasse zu halten
        *
        * @var Singleton
        */
       protected static $_instance = null;
       protected $mail;

       /**
        * get service
        *
        * Falls die einzige Service-Instanz noch nicht existiert, erstelle sie
        * Gebe die einzige Service-Instanz dann zurück
        *
        * @return   Singleton
        */
       public static function getService()
       {
           if (null === self::$_instance)
           {
               self::$_instance = new self;
           }
           return self::$_instance;
       }

       /**
        * clone
        *
        * Kopieren der Service-Instanz von aussen ebenfalls verbieten
        */
       protected function __clone() {}

       /**
        * constructor
        *
        * externe Instanzierung verbieten
        */
       protected function __construct() {
           //new PHPMailerAutoload();
           $this->mail = new PHPMailer();

           $configs = ConfigService::getService()->getConfigs();
           $this->mail->SMTPDebug = 3;          //Gibt starke Debugging Ausgaben aus - für Realease Deaktivieren (später auf 2)
           $this->mail->setLanguage('de');
           $this->mail->IsSendmail();
           $this->mail->Host = $configs['email_host'];
           $this->mail->Port = $configs['email_port'];
           $this->mail->SMTPSecure = "ssl";
           $this->mail->SMTPAuth = true;
           $this->mail->Username = $configs['email_username'];
           $this->mail->Password = $configs['email_password'];
           $this->mail->From       = $configs['email_username'];
           $this->mail->FromName   = "Studienführer - VWI-ESTIEM-Karlsruhe e.V.";
           $this->mail->CharSet =  'UTF-8';
           $this->mail->isHTML(true);
       }


       /**
        * sendet Email
        *
        * Sendet eine Email an den Nutzer. Gibt ein gewisses Format vor
        */
       public function sendEmail($toEmail, $userName, $subject, $body){
           $this->mail->AddAddress($toEmail, $userName);
           $this->mail->Subject = $subject;

             $this->mail->AddEmbeddedImage(__DIR__ . '/../../pictures/logo_studi.png', 'studilogo.png', 'studilogo.png');
             $this->mail->AddEmbeddedImage(__DIR__ . '/../../pictures/email/facebook.png', 'facebook.png', 'facebook.png');
             $this->mail->AddEmbeddedImage(__DIR__ . '/../../pictures/email/instagram.png', 'instagram.png', 'instagram.png');

           $htmlWithoutCSS = '
            <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional //EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
            <html>
                <head>
                    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
                    <title>My Mail</title>
                    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
                </head>
                '.'
                <body>
                    <p>Hallo $userName,</p>
                    $body
                </body>
            </html>
            ';
           $cssToInlineStyles = new CssToInlineStyles();
           $this->mail->Body = $cssToInlineStyles->convert(
                $htmlWithoutCSS,
                file_get_contents(__DIR__ . '/../../res/css/emails.css')
            );
           if(!$this->mail->Send()){
               return false;
           }else{
               return true;
           }
       }
    }

?>

php email
2个回答
2
投票

你问题的原因是这一行

$this->mail->AddAddress($toEmail, $userName);

每次调用时,都会在地址列表中添加新的电子邮件地址。这导致您向最后一个管理员发送一封电子邮件,向第二位管理员发送2封电子邮件等等

public function sendEmail($toEmail, $userName, $subject, $body){似乎没有被设计为每次实例化多次调用,但一个简单的更改将解决问题

$mail->ClearAllRecipients();添加到这样的方法中。

public function sendEmail($toEmail, $userName, $subject, $body){

    // remove previous recipients if being called multiple times in a loop
    $this->mail->ClearAllRecipients();  

    $this->mail->AddAddress($toEmail, $userName);
    $this->mail->Subject = $subject;

    . . .

1
投票

您每次循环使用相同的实例,每次调用sendEmail()时,它都会向实例添加地址。

您可以每次创建一个新实例,而不是调用getService(),它将重新开始。

while($row = mysqli_fetch_assoc($result)){    
    $mailer = new EmailService;  
    $mailer->sendEmail($row['email'], $row['first_name'], $subject, $body);
}
© www.soinside.com 2019 - 2024. All rights reserved.