Search code examples
phpphpmailer

Getting invalid mail error during phpmailer bulk mail sending


php mailer is mass mail, but if a mail address in a record is incorrect, it stops sending mail. How can I skip that address and continue.

I RETURN ALL MY CODES FROM MY DATABASE TO LIST WITH FOREACH HERE I didn't have a problem when I tried my codes on a array of two different emails of mine

<?php

    $mail = new PHPMailer(true);
    try {
        //Server Ayarları
        $mail->SMTPDebug = SMTP::DEBUG_SERVER;
        $mail->Host="x";
        $mail->SMTPAuth= true;
        $mail->Username="x@x";
        $mail->isSMTP();
        $mail->Password="x;
        $mail->CharSet="utf8";
        $mail->Port=587;
        //Alıcı Ayarları
        $mail->setFrom('x', 'x');
        $gonulluler=$database->select($_SESSION["type"],"eposta");
        foreach ($gonulluler as $gonullu){
            $mail->addBCC($gonullu);
        }

        //Gönderi ayarları
        $mail->isHTML(true);
        $mail->Subject=$baslik;
        $mail->Body=$icerik;
        if($mail->send()){
            $alert=array(
                "message"=>"Mail Başarılı Bir Şekilde Gönderildi",
                "type" => "success"
            );
        }else{
            $alert=array(
                "message"=>"Mail Gönderilirken Bir Hata İle Karşılaşıldı",
                "type" => "danger"
            );
        }

    }catch (Exception $e){
        $alert=array(
                "message"=>$e->getMessage(),
                "type" => "danger"
            );
    }
        


Solution

  • You could check if the email address is valid, and if the mailserver will respond, before using $mail->addBCC(). This function can do both:

    function isValidEmailAddress($email, $performDomainCheck = FALSE)
    // validate an email address, TRUE if the email address has the email address format and the domain exists
    {
       $atSignIndex = strrpos($email,'@');
       // no @ sign
       if (is_bool($atSignIndex) && !$atSignIndex) return FALSE;
       // take parts
       $domain    = substr($email,$atSignIndex+1);
       $name      = substr($email,0,$atSignIndex);
       $domainLen = strlen($domain);
       $nameLen   = strlen($name);
       // name part length exceeded
       if ($nameLen < 1 || $nameLen > 64) return FALSE;
       // domain part length exceeded
       if ($domainLen < 1 || $domainLen > 255) return FALSE;
       // local part starts or ends with '.'
       if ($name[0] == '.' || $name[$nameLen-1] == '.') return FALSE;
       // local part has two consecutive dots
       if (preg_match('/\\.\\./', $name)) return FALSE;
       // character not valid in domain part
       if (!preg_match('/^[A-Za-z0-9\\-\\.]+$/', $domain)) return FALSE;
       // domain part has two consecutive dots
       if (preg_match('/\\.\\./', $domain)) return FALSE;
       // character not valid in local part unless local part is quoted
       if (!preg_match('/^(\\\\.|[A-Za-z0-9!#%&`_=\\/$\'*+?^{}|~.-])+$/',str_replace("\\\\","",$name)))
       {
         if (!preg_match('/^"(\\\\"|[^"])+"$/',str_replace("\\\\","",$name))) return FALSE;
       }
       // domain not found in DNS?
       if ($performDomainCheck)
       {
    //     $domain = idn_to_ascii($domain);   function not known yet (php 5.3 on 24-10-2015)
         if (!(checkdnsrr($domain,"MX") || checkdnsrr($domain,"A"))) return FALSE;
       }
       // it's oke
       return TRUE;
    }
    

    I didn't update the style of this function. It is not perfect, but using something like this will make your mass mailer work a lot better. Your code would look something like this:

        foreach ($gonulluler as $gonullu){
            if (isValidEmailAddress($gonullu, TRUE) {
                $mail->addBCC($gonullu);
            }
        }
    

    You could add an else part to notify yourself of the invalid email addresses.