Problème envoi de mails, besoin d'une temporisation

Eléphanteau du PHP | 38 Messages

01 oct. 2014, 13:35

Bonjour,

j'ai un service qui envoi des mails en masse, qui pour l'instant n'est utilisé que pour mes sites internet.
Donc je n'ai que 978 emails à qui je suis susceptible d'envoyer des emails.
Je précise que ce sont des doubles optin.
La personne s'inscrit volontairement et elle reçoit un email pour confirmer que son adresse est bien la bonne et qu'elle souhaite être inscrite.

Mon soucis est que depuis plusieurs mois, mes mails de tests partent, lorsque c'est sur 3 boites différentes, mais dès que j'envoi sur 1000 boites
ça part pas.
Puis si je réessaye avec juste 3 boites cela ne part toujours pas...
On me dit que c'est peut être un blocage sur un envoi trop important d'un coup.
Bref c'est pas terrible.

Mon hébergeur ne me permet pas un accès à mes logs, mais m'a proposé de faire des tests de son côté, sauf que cela semble prendre du temps.
Il me suggère de ne pas envoyer plus de 30 mails par minute. Cela me donnera donc 1000 mails en plus d'une demie heure, mais pourquoi pas !

Sauf que mon code n'allait pas dans ce sens.
Et je ne voudrais pas tout planter, que me conseillez-vous ?
Voici mon code actuel
#!/usr/local/bin/php 
<?php
set_time_limit(0);
include('mail_class.php');
include ('config.php');
$mailsent=0;
$rs1=mysql_query("select * from mailque where st<en order by ID");
while($arr=mysql_fetch_array($rs1)) {
$id=$arr[0];
$st=$arr[1];
$en=$arr[2];
$subject=$arr[3];
$message=$arr[4];
$format=$arr[5];
$aid=$arr[7];

$subss=mysql_query("select * from autoresadminsettings where ID=$aid");
if(mysql_num_rows($subss)>0) {
$subm=mysql_fetch_array($subss);
$username1=$subm[4];
//Ajout nom de l'autorepondeur
$nom_autorep=$subm[1];

if($autofolder=="") $username=$username1;
else $username="$autofolder/$username1";

$webmasteremail=$subm[3];
}

$usercount=0;
$st1=$st-1;
$en1=$en+1;
for($i=1;$i<=$batchsize;$i++) {
$result=mysql_query("select * from subscribers where aid=$aid and status=1 and ID>$st1 and ID<$en1 order by ID limit 0,1");
if(mysql_num_rows($result)>0) {

$rs=mysql_fetch_row($result);
$st1=$rs[0];
	$body=str_replace("{email}",$rs[2],$message);
	$body=str_replace("{name}",$rs[1],$body);
	$body=str_replace("{ip}",$rs[4],$body);
	$body=str_replace("{date}",$rs[5],$body);

	$subject1=str_replace("{email}",$rs[2],$subject);
	$subject1=str_replace("{name}",$rs[1],$subject1);
	$subject1=str_replace("{ip}",$rs[4],$subject1);
	$subject1=str_replace("{date)",$rs[5],$subject1);

$from=$webmasteremail;
   	$header = "From: $sitename<$from>\n";
if($format==1) 
	$header .="Content-type: text/plain; charset=UTF-8\n";
else
	$header .="Content-type: text/html; charset=UTF-8\n";
	$header .= "Reply-To: <$from>\n";
	$header .= "X-Sender: <$from>\n";
	$header .= "X-Mailer: PHP4\n";
	$header .= "X-Priority: 3\n";
	$header .= "Return-Path: <$from>\n";


if($format==2)
$message1=$body."<hr>Si vous souhaitez ne plus recevoir de messages, cliquez sur le lien suivant : <a href=$siteurl/$username/remove.php?id=$rs[0]&email=$rs[2]>$siteurl/$username/remove.php?id=$rs[0]&email=$rs[2]</a><br>";
else 
$message1=$body."\n========================================\nSi vous souhaitez ne plus recevoir de messages, cliquez sur le lien suivant : $siteurl/$username/remove.php?id=$rs[0]&email=$rs[2]";

$subject1=stripslashes($subject1);
$message1=stripslashes($message1);

// ajout email du webmaster : $webmasteremail et du nom de l'autorepondeur : $nom_autorep
$idmembre = $aid.'-membre';
// ajout du code du membre : $idmembre
//      mail($rs[2],$subject1,$message1,$header);

if (new Mail($rs[2],$subject1,$message1,$format,$webmasteremail,$nom_autorep,$idmembre)) { }

        $usercount=$usercount+1;
        //echo($usercount .". Message Successfully Send to: ".$rs[2]."<br>");

$mailsent++;
if($mailsent==$batchsize) { 
$st2=$st-1;
$en2=$en+2;
if($st2==$st1) {
$rsup=mysql_query("update mailque set st=$en2 where ID=".$arr[0]);
}
else {
$rsup=mysql_query("update mailque set st=".($st1+1)." where ID=".$arr[0]);
}

mysql_close($dbconnect);
exit;
}

}
      } // end of for loop
$st2=$st-1;
$en2=$en+2;
if($st2==$st1) {
$rsup=mysql_query("update mailque set st=$en2 where ID=".$arr[0]);
}
else {
$rsup=mysql_query("update mailque set st=".($st1+1)." where ID=".$arr[0]);
}
}
mysql_close($dbconnect);
?>
Pour info ma table mailque est ainsi :
`mailque` (
  `ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `st` int(10) unsigned NOT NULL,
  `en` int(10) unsigned NOT NULL,
  `subject` mediumtext,
  `message` mediumtext,
  `mtype` int(10) unsigned NOT NULL,
  `Date` datetime DEFAULT NULL,
  `aid` int(10) unsigned NOT NULL,
  PRIMARY KEY (`ID`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 
Merci beaucoup pour votre aide pour ce problème qui me pollue la vie depuis quelques mois.

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

01 oct. 2014, 23:02

salut,

coté code j'ai l'impression que tu peux faire un peu mieux, comme par exemple sélectionner les infos avec une jointe (ou plusieurs ce n'est pas un problème) et ainsi limiter le nombre de requête (n+1 au total et ton dans ton cas 1+ n + "$batchsize" x 2 x n + n, ce que te montre que plus tu as de résultat dans la requête tu vas faire de requête.

Donc optimiser ton modèle de donnée, ou l'utiliser de façon optimale (requête optimisée en nombre réduit utiliser des requêtes préparer, je t'invite d'ailleurs à utiliser PDO ou mysqli en lieu et place de l’extension mysql qui est vouée à disparaître) va te permettre d'avoir un gain de temps (bon c'est pas non plus 2minutes de gain sur 1k mail mais ça chiffre).

côté architecture, limite le nombre d'email selectionné dans la requête (limit 0,30) par contre il faut que tu flag les email envoyés (utilité des update en fin de script ?).

Par contre il faut t'assurer de ne dépasser la limite.

une autre possibilité et de compter le nombre d'email que tu envois et d'arrêter le script quand tu arrive a 30 mais c'est un peu crade de faire une requête de 5 millions de tuple pour en utiliser 30 :mrgreen:

je ne sais pas ce que fait ta classe Mail mais elle si peux utiliser un autre serveur SMTP que celui par défaut de php tu peux peux être évoter ce problème (comme te le propose phpmailer par exemple).

@+
Il en faut peu pour être heureux ......