Certains mails ne partent pas avec un envoi PHP et SMTP

Eléphanteau du PHP | 38 Messages

12 août 2014, 22:57

Bonsoir,

J'ai un script d'envoi de mails via SMTP depuis un fonction PHP.
Mon site génère des envois plus ou moins important de mails, afin de garantir une bonne délivrabilité j'utilise un envoi via SMTP.
Jusqu'à récemment tout fonctionnait parfaitement. j'ai du changer d'hébergeur et malgré des contacts réguliers avec l'assistance de mon
hébergeur, il est impossible de trouver le "problème", aussi je vous demande votre aide.

J'ai une page appelé par une tâche CRON toutes les 10 minutes :
envoidemails.php
dans laquelle je met dès le départ : include('mail_class.php');

Plus loin dans cette page (envoidemails.php) j'appelle :
if (new Mail($arr[2],$subject,$message,$format,$webmasteremail,$nom_autorep,$idmembre)) { }

Voici le code de "envoidemails.php" :
class Mail{
    private $smtpServer = 'xxxx'; //     YOURSMTPHOST    Enter the smtp server
    private $port = '26';
    private $timeout = '45';
    private $uname = '[email protected]';             //   YourSiteName     enter uname
    private $username = '[email protected]';             //        YourEmail       enter username (smtp server)
    private $password = 'xxxx';             //  YourPassword enter password (smtp server)
    private $newline = "\r\n";
    private $localdomain = 'xxxx';          //enter localdomain.
    private $charset = 'utf-8';  //charser code
    private $contentTransferEncoding = false;

    // Do not change anything below
    private $smtpConnect = false;
    private $to = false;
    private $subject = false;
    private $message = false;
    private $format = 1;
    private $headers = false;
    private $logArray = array(); // Array response message for debug
    private $Error = '';

        //ajour de $webmasteremail, $nom_autorep
    public function __construct($to, $subject, $message, $format, $webmasteremail, $nom_autorep, $idmembre) {
        $this->to = &$to;
        $this->subject = &$subject;
        $this->message = &$message;
        echo "message : ".$this->message;
        $this->format = &$format;
        $this->webmasteremail = &$webmasteremail;
        $this->nom_autorep = &$nom_autorep;
        $this->idmembre = &$idmembre;
        $this->newmailmembre = $this->idmembre.'@xxxx';
        // Connect to server
        if(!$this->Connect2Server()) {
                // Display error message
            echo $this->Error.$this->newline.' '.$this->newline;
            print_r($this->logArray);
            echo $this->newline.' '.$this->newline;
            return false;
        }
        return true;
    }

    private function Connect2Server() {
        // Connect to server
        $this->smtpConnect = fsockopen($this->smtpServer,$this->port,$errno,$error,$this->timeout);
        $this->logArray['CONNECT_RESPONSE'] = $this->readResponse();

        if (!is_resource($this->smtpConnect)) {
            return false;
        }
        $this->logArray['connection'] = "Connection accepted: $smtpResponse";
        // Hi, server!
        $this->sendCommand("EHLO $this->localdomain");
        $this->logArray['EHLO'] = $this->readResponse();
        // Let's know each other
        $this->sendCommand('AUTH LOGIN');
        $this->logArray['AUTH_REQUEST'] = $this->readResponse();
        // My name...
        $this->sendCommand(base64_encode($this->username));
        $this->logArray['REQUEST_USER'] = $this->readResponse();
        // My password..
        $this->sendCommand(base64_encode($this->password));
        $this->logArray['REQUEST_PASSWD'] = $this->readResponse();
        // If error in response auth...
        if (substr($this->logArray['REQUEST_PASSWD'],0,3)!='235') {
            $this->Error .= 'Authorization error! '.$this->logArray['REQUEST_PASSWD'].$this->newline;
            return false;
        }
        // "From" mail...
        $this->sendCommand("MAIL FROM: $this->username");
        $this->logArray['MAIL_FROM_RESPONSE'] = $this->readResponse();
        if (substr($this->logArray['MAIL_FROM_RESPONSE'],0,3)!='250') {
            $this->Error .= 'Mistake in sender\'s address! '.$this->logArray['MAIL_FROM_RESPONSE'].$this->newline;
            return false;
        }
        // "To" address
        $this->sendCommand("RCPT TO: $this->to");
        $this->logArray['RCPT_TO_RESPONCE'] = $this->readResponse();
        if (substr($this->logArray['RCPT_TO_RESPONCE'],0,3)!='250') {
            $this->Error .= 'Mistake in reciepent address! '.$this->logArray['RCPT_TO_RESPONCE'].$this->newline;
        }
        // Send data to server
        $this->sendCommand('DATA');
        $this->logArray['DATA_RESPONSE'] = $this->readResponse();
        // Send mail message
        if (!$this->sendMail()) return false;
        // Good bye server! =)
        $this->sendCommand('QUIT');
        $this->logArray['QUIT_RESPONSE'] = $this->readResponse();
        // Close smtp connect
        fclose($this->smtpConnect);
        return true;
    }
    // Function send mail
    private function sendMail() {
        $this->sendHeaders();
        $this->sendCommand($this->message);
        $this->sendCommand('.');
        $this->logArray['SEND_DATA_RESPONSE'] = $this->readResponse();
        if(substr($this->logArray['SEND_DATA_RESPONSE'],0,3)!='250') {
            $this->Error .= 'Mistake in sending data! '.$this->logArray['SEND_DATA_RESPONSE'].$this->newline;
            return false;
        }
        return true;
    }
    // Function read response
    private function readResponse() {
        $data="";
        while($str = fgets($this->smtpConnect,4096))
        {
            $data .= $str;
            if(substr($str,3,1) == " ") { break; }
        }
        return $data;
    }
    // function send command to server
    private function sendCommand($string) {
        fputs($this->smtpConnect,$string.$this->newline);
        return ;
    }
    // function send headers
    private function sendHeaders() {
        $this->sendCommand("Date: ".date("D, j M Y H:i:s")." +0700");
                //changement $this->sendCommand("From: $this->uname <$this->username>"); en $this->sendCommand("From: $this->nom_autorep <$this->webmasteremail>");
        $this->sendCommand("From: $this->nom_autorep <$this->webmasteremail>");
                //changement $this->sendCommand("Reply-To: <$this->username>"); en $this->sendCommand("Reply-To: <$this->webmasteremail>");
        $this->sendCommand("Reply-To: <$this->webmasteremail>");
                //ajout $this->sendCommand("Sender: <$this->newmailmembre");
                $this->sendCommand("Sender: <$this->newmailmembre>");
        $this->sendCommand("To: <$this->to>");
        $this->sendCommand("Subject: $this->subject");
        $this->sendCommand("MIME-Version: 1.0");
if(($this->format)==1)
        $this->sendCommand("Content-Type: text/plain; charset=$this->charset");
else
        $this->sendCommand("Content-Type: text/html; charset=$this->charset");
        if ($this->contentTransferEncoding) $this->sendCommand("Content-Transfer-Encoding: $this->contentTransferEncoding");
        $this->sendCommand($this->newline);
//              print_r($this->to); 
        return ;
    }

    public function __destruct() {
        if (is_resource($this->smtpConnect)) fclose($this->smtpConnect);
    }


}

Mon problème est qu'en faisant partir un mail simple :
sujet :
Test d un second message
message :
You are receiving this message because you/someone else had subscribed to our list with this email address. For removal check the bottom instructions.
=======================================
Voici un second message!
=======================================

Si vous souhaitez ne plus recevoir de messages, cliquez sur le lien suivant : http://*****remove.php?id=***&email=****
=======================================

Et également un mail plus complexe avec un titre et un corps de message contenant des accents circonflexes, des apostrophes etc :
Vous recevez ce message parce que vous vous êtes inscrit à notre liste avec cette adresse e-mail. Vous pouvez vous désabonner en fin de mail. ======================================= Bonjour Damien, Avez-vous bien lu le livre concernant les "****"? Alors qu'en avez-vous pensé?
[ etc...] ======================================= Si vous souhaitez ne plus recevoir de messages, cliquez sur le lien suivant : http://*****remove.php?id=***&email=**** =======================================

Le premier mail part bien, le second lui ne s'envoi pas (en tout cas n'arrive pas).
J'ai évidemment testé sur la même boîte mail et sur une boîte différente.

J'ai du mal à faire du debug sur la fonction pour savoir là où cela pourrait gêner, je ne suis pas à l'origine du code de départ.

Merci d'avance pour toute l'aide que vous pourriez m'apporter étant donné que je butte depuis des jours sur ce problème.

ViPHP
ViPHP | 1996 Messages

14 août 2014, 10:04

As tu accès aux logs ?
It is nice to be important but it is more important to be nice
http://www.aureuswebfactory.fr

Eléphanteau du PHP | 38 Messages

20 août 2014, 16:53

Non je ne pense pas.
En tout cas je n'ai rien vu de tel.

Merci par avance pour votre aide.

ViPHP
ViPHP | 1996 Messages

21 août 2014, 07:31

Bon cela sent les caractères mal interprétés.
Je vois que utilise dans la classe une variable privée "charset" qui mentionne le jeu de caractères utf-8.

Un peu plus loin, tu l'utilises :
$this->sendCommand("Content-Type: text/plain; charset=$this->charset");
Moi, je préfère (même si je ne pense pas que cela vienne de là):
 $this->sendCommand("Content-Type: text/plain; charset=".strtoupper($this->charset));
Et pourquoi pas, essayes d'utiliser :
echo "message : ".utf8_encode($this->message);
It is nice to be important but it is more important to be nice
http://www.aureuswebfactory.fr

Eléphanteau du PHP | 38 Messages

26 août 2014, 09:53

Bonjour,

Merci beaucoup pour cette réponse Aureusms, je pense aussi que cela doit venir de caractères mal intérprétés.

A quel endroit dois-je utiliser :
echo "message : ".utf8_encode($this->message);
Merci encore pour votre aide.

Eléphanteau du PHP | 38 Messages

26 août 2014, 10:06

En faisant un affichage utf8_encode cela donne par exemple : Cliquez ici pour un accès rapide

ViPHP
ViPHP | 1996 Messages

27 août 2014, 08:41

Ok c'est normal si ta page php est encodée en autre chose que UTF-8.
De mon côté, j'encode toutes mes pages php en "UTF-8 sans BOM". Avant j'utilisais le jeux de caractères européen ISO 8859-15 pour avoir les caractères € mais j'avais ce genre de problème. Maintenant, UTF-8 permet d'avoir quasiment tous les jeux de caractères de la planète.
Dernière chose sur UTF-8 : Généralement, lorsqu'on utilise un jeu de caractères UTF (de type 16 ou 32), un "mot" appellé BOM (pour Byte Order Mark) est ajouté de façon invisible pour l'utilisateur pour marquer la page et indiquer au programme qui lit la page que le jeu de caractères est un UTF. Ce BOM est inutile pour le jeu de caractères UTF-8 mais est très souvent ajouté par les programmes d'édition.
Si tu n'enlèves pas le BOM tu risques d'avoir deux choses :
  • Si tu inclus la page encodée en UTF-8 avec BOM dans une autre, tu auras l’affichage de :  ou un espace supplémentaire
    Si tu rediriges cette page encodée en UTF-8 avec BOM, tu auras :

Code : Tout sélectionner

Warning: Cannot modify header information
Bref, encodes toutes te spages en UTF-8 sans BOM (avec notepad++ par exemple si tu édites tes pages sous WIN).

Est ce que le message part maintenant et est ce les caractères sont bien lisibles dans le message reçu ?
It is nice to be important but it is more important to be nice
http://www.aureuswebfactory.fr

Eléphanteau du PHP | 38 Messages

27 août 2014, 09:24

Bonjour,

Encore merci pour votre aide.
J'avais déjà fait cette manipulation mais par acquis de conscience j'ai refais un "convertir en UTF-8 sans bom".
Et j'ai refais un envoi, malheureusement cela n'a pas fonctionné.
Et en utilisant :
echo "<br />message : ".utf8_encode($this->message);
j'ai toujours "Cliquez ici pour un accès rapide"

Je précise que par rapport à ma BDD j'utilise
  $dbconnect=mysql_connect($dbhost,$dbuser,$dbpass);
  mysql_select_db($dbname);
  mysql_query("SET NAMES 'utf8'");
Encore pour merci pour votre aide, j'aimerai vraiment que tout soit fonctionnel, mais je ne trouve pas de solution...

ViPHP
ViPHP | 1996 Messages

27 août 2014, 12:12

Hmmm... il faut vraiment que tu es accès aux logs.
Es-tu sur ton propre serveur ? En mutualisé ?
It is nice to be important but it is more important to be nice
http://www.aureuswebfactory.fr

ynx
Mammouth du PHP | 586 Messages

27 août 2014, 12:32

Salut,

Où vois tu le message "Cliquez ici pour un accès rapide" ? J'avais compris que tu ne recevais pas le mail.

Ces caractères indique que ton message est bien encodé en utf-8 mais ton document (mail ou page html) n'utilise pas le bon charset.
Si tu vois ce message dans le mail, vérifie que les entêtes de ton code sont bien présente en regardant le code source du mail (raccourci Ctrl+U dans Thunderbird).
Si tu vois ce message dans un document html, définie le charset utilisé avec la fonction header() ou en ajoutant une balise meta.

Eléphanteau du PHP | 38 Messages

27 août 2014, 13:37

Hmmm... il faut vraiment que tu es accès aux logs.
Es-tu sur ton propre serveur ? En mutualisé ?
Je suis en mutualise mais j'ai demande les logs, mon hébergeur souhaite pouvoir tester mon script, pas évident de l'adapter.
Salut,

Où vois tu le message "Cliquez ici pour un accès rapide" ? J'avais compris que tu ne recevais pas le mail.

Ces caractères indique que ton message est bien encodé en utf-8 mais ton document (mail ou page html) n'utilise pas le bon charset.
Si tu vois ce message dans le mail, vérifie que les entêtes de ton code sont bien présente en regardant le code source du mail (raccourci Ctrl+U dans Thunderbird).
Si tu vois ce message dans un document html, définie le charset utilisé avec la fonction header() ou en ajoutant une balise meta.
Comme je l'ai dis je met un écho qui utilise utf8-encode pour afficher mon message qui est envoyé. Si je ne le met pas tout s'affiche parfaitement.
Donc non mes mails ne partent toujours pas.

Merci pour votre aide.

ViPHP
ViPHP | 1996 Messages

27 août 2014, 14:32

Salut,

Moi je suis en mutualisé sur de nombreux sites chez OVH et je peux consulter les logs via une de leur pages spéciales.
Tu es chez qui ?
It is nice to be important but it is more important to be nice
http://www.aureuswebfactory.fr

ynx
Mammouth du PHP | 586 Messages

27 août 2014, 15:56

Comme je l'ai dis je met un écho

Ok donc l'encodage de ton message est correct, c'est uniquement ton document html qui n'utilise pas le bon charset.
Pour confirmer tu peux définir le charset dans l'entête http en utilisant la fonction header() avant ton echo :
header('Content-Type: text/html; charset=utf-8');
echo 'accès'; // affiche accès avec l'accent
Ca ne résout pas ton problème mais on sait au moins que ce n'est pas un problème du à l'encodage du message.

Eléphanteau du PHP | 38 Messages

01 sept. 2014, 22:08

Bonsoir,

Merci beaucoup pour votre aide.
J'ai demandé à mon hébergeur (o2switch) de me dire si je peux avoir accès aux logs d'envoi
de mes mails.

Par contre mes mails sont envoyés après un changement dans ma BDD :
ALTER TABLE `mailque` CONVERT TO CHARACTER SET utf8;
La question est :
Est-ce que je dois faire un changement dans mon formulaire où je rentre le texte de mes mails ?

Merci encore.