使用Foreach的Bug,重复相同的变量

时间:2019-01-28 17:23:03

标签: php

我为创建的批量邮件平台构建了一个邮件功能,除了要替换的链接之外,其他所有功能均正常运行,所有补救措施都使用相同的电子邮件变量,这与变量$一起发生跟踪器也是如此,但已将其添加到sendMail函数中,此问题已得到修复,对于str_replace来说无效,该函数原本应该在每次迭代中更改电子邮件,就像它在每次迭代中发送邮件一样,无法理解为什么变量保持如果要迭代,则相同。

我已注释掉问题所在的代码为“ //问题在这里”,for循环为“ foreach($ emails as $ email){”

class mailer{

    private $max = 1000; // Máximo de envios de acordo com o servidor
    private $connect;

    public function __construct($host,$user,$password,$db){

        $this->connect = new mysqli($host,$user,$password,$db);  

    }

    public function enviarCampanhas(){

        $connect = $this->connect;
        $data = date("Y-m-d");
        $get = $connect->query("SELECT * FROM campanhas WHERE status = 0 OR status = 3 AND data_inicio LIKE '$data%'");
        $count = $get->num_rows;
        $max_per_campanha = $this->max / $count;

        while($fetch = $get->fetch_array(MYSQLI_ASSOC)){
            // Falta contagem do array da lista para saber a que emails enviar e depois marcar na campanha quantos já foram enviados

            // Calcular o nr de email na lista
            $cid = $fetch['id'];
            $total = $fetch['total'];
            $enviado = $fetch['enviado'];
            $assunto = utf8_decode($fetch['assunto']);
            $template_id = $fetch['template_id'];
            $get_campaign = $connect->query("SELECT * FROM campanhas WHERE id = '$cid'");
            $fetch_campaign = $get_campaign->fetch_array(MYSQLI_ASSOC);
            $lista_id = $fetch_campaign['lista_id'];
            $user_id = $fetch_campaign['user_id'];

            $get_template = $connect->query("SELECT * FROM templates WHERE id = '$template_id'");
            $fetch_template = $get_template->fetch_array(MYSQLI_ASSOC);
            $corpo = $fetch_template['codigo'];
            $corpo = str_replace('*','<style>', $corpo);
            $corpo = $corpo."</style>";


            // Trocar links para contabilitizar
            $html = $corpo;
            //Create a new DOM document
            $dom = new DOMDocument;

            //Parse the HTML. The @ is used to suppress any parsing errors
            //that will be thrown if the $html string isn't valid XHTML.
            @$dom->loadHTML($html);

            //Get all links. You could also use any other tag name here,
            //like 'img' or 'table', to extract other tags.
            $links = $dom->getElementsByTagName('a');

            //Iterate over the extracted links and display their URLs
            foreach ($links as $link){
                $old_link = $link->getAttribute('href');
                $new_link = "https://".$_SERVER['SERVER_NAME']."/scripts/link.php?link=".$link->getAttribute('href')."&campaign_id=".$cid;
                $html = str_replace($old_link,$new_link,$html);
            }

            $corpo = $html;

            $get_lista = $connect->query("SELECT * FROM listas WHERE lista_id = '$lista_id'");
            $fetch_lista = $get_lista->fetch_array(MYSQLI_ASSOC);
            $emails = $fetch_lista['email'];
            $unsubscribers = $fetch_lista['unsubscribed'];
            $unsubscribers = explode(",",$unsubscribers);
            $emails = explode(",",$emails);
            $emails_new = array_diff_key($emails, array_values($unsubscribers)); 

            $email_nr = 0;
            $count = 1;

            // the problem is here
            foreach($emails as $email){

                if($count == $max_per_campanha){
                    // Parar
                }else{

                    $email = trim($email);
                    $tracker = '<img src="http://website.com/scripts/save_click.php?campaign_id='.$fetch['id'].'&email='.$email.'" />';
                    require_once('../configs/global.php');

                    // This is what is not working properly
                    $novo_url = $config['global']['website']."/scripts/unsubscribed.php?email=$email&campaign_id=$cid";
                    $corpo = str_replace("http://website.com/scripts/unsubscribe.php?replaceparam=x", $novo_url, $corpo);

                    $app = new app;
                    if($app->sendMail($email,$assunto,$tracker."</br>".$corpo) == true){
                        // Guardar emails entregues
                        $connect->query("UPDATE campanhas SET sucess_delivered = sucess_delivered + 1 WHERE id = '$cid'");
                        // Adicionar DB sucess_deliveries , com emails bounced em array
                        //echo $corpo;

                    }else{
                        // Adicionar DB bounced , com emails bounced em array
                        $connect->query("UPDATE campanhas SET bounced = bounced + 1 WHERE id = '$cid'");
                    }
                    $count++;
                }
            }


            // the problem is inside foreach

            $enviado = $enviado + $count;

            if($enviado >= $total){
                $connect->query("UPDATE campanhas SET enviado = '$total',status = 1 WHERE id='$cid'");
                echo "excedeu, completa";
            }else{    
                $connect->query("UPDATE campanhas SET enviado = enviado + '$count' WHERE id='$cid'");
                echo "não completa";
            }  
        }
    }
}

由于它正在遍历数组中的每封电子邮件,并且该数组清晰可读,甚至跟踪器也在更改自身,因此它是电子邮件,我不明白为什么str_replace向每个收件人发送相同的退订电子邮件作为参数

1 个答案:

答案 0 :(得分:1)

问题出在这一行:

$corpo = str_replace("http://website.com/scripts/unsubscribe.php?replaceparam=x", $novo_url, $corpo);

第一次,$corpo不再包含http://website.com/scripts/unsubscribe.php?replaceparam=x,因为它已被$novo_url取代。因此,在将来的迭代中,它根本不会更新$corpo

不要将str_replace()的结果分配回相同的变量,而是分配给新的变量。您需要保留原始字符串作为模板。

foreach($emails as $email){

    if($count == $max_per_campanha){
        // Parar
    }else{

        $email = trim($email);
        $tracker = '<img src="http://website.com/scripts/save_click.php?campaign_id='.$fetch['id'].'&email='.$email.'" />';
        require_once('../configs/global.php');

        // This is what is not working properly
        $novo_url = $config['global']['website']."/scripts/unsubscribed.php?email=$email&campaign_id=$cid";
        $new_corpo = str_replace("http://website.com/scripts/unsubscribe.php?replaceparam=x", $novo_url, $corpo);

        $app = new app;
        if($app->sendMail($email,$assunto,$tracker."</br>".$new_corpo) == true){
            // Guardar emails entregues
            $connect->query("UPDATE campanhas SET sucess_delivered = sucess_delivered + 1 WHERE id = '$cid'");
            // Adicionar DB sucess_deliveries , com emails bounced em array
            //echo $new_corpo;

        }else{
            // Adicionar DB bounced , com emails bounced em array
            $connect->query("UPDATE campanhas SET bounced = bounced + 1 WHERE id = '$cid'");
        }
        $count++;
    }
}