Maintenir une liste d’adresses emails indisponibles

Contrairement à un serveur SMTP, la fonction mail de PHP ne supporte pas la confirmation à la réception ce qui rend difficile la tâche de déterminer si une adresse est valide. Certains hébergeurs comme OVH renvoient périodiquement une liste d’adresses produisant des erreurs (boite indisponible, adresse inconnue…). Voici comment constituer un script pour traiter ce genre de liste.

Pour démarrer, vous pouvez créer un formulaire en HTML ressemblant à celui-ci. Le POST est à rediriger sur la page PHP contenant les fonctions destinées à filtrer et à enregistrer les adresses emails.

echo "<form action='ExtractEmail.php' method='post'>";
echo "Erreurs mail:<br/><textarea name='emailsource' cols='50' rows='7'></textarea>";
echo "<br/><INPUT type='submit' name='submit' value='Envoyer'>";
echo "</form>";

Ensuite, au niveau PHP on teste si emailsource (le textarea) est setté (si vous souhaitez faire les choses dans les règles de l’art vous pouvez également tester le submit). Le texte contenant les emails est passé à deux fonctions pour former un array. Le fonction standard array_unique réduit le contenu d’un array à des occurences uniques et array_filter permet de retirer les occurences définies par une fonction nommée en deuxième argument. Les fonctions extract_emails et filter_emails sont décrites plus loin.

Notez la présence d’un ‘ON DUPLICATE KEY UPDATE UPDATE id=id’ au niveau de l’enregistrement dans la base de données. Cette requête se contente de redonner la même valeur à la clé primaire lorsque une adresse email est déjà présente dans la table.

if( isset($_POST["emailsource"]) ){
    $emailsource = $_POST["emailsource"];
     
    $mail_array = array_unique( array_filter( extract_emails($emailsource), 'filter_emails' ) );
 
    //echo "<pre>";
    //print_r($mail_array);
    //echo "</pre>";
     
    foreach( $mail_array as $email ) {
        $db->query('INSERT INTO email_failures SET email="' . $db->escape( $email ) . '", date_fail= NOW() ON DUPLICATE KEY UPDATE id=id' );
    }
     
    echo "Ajoutés:";
     
    echo "<p>";
     
    foreach( $mail_array as $email ) {
        echo $email . "<br/>";
    }
     
    echo "</p>";
 
}

Les fonctions extract_emails et filter_emails sont décrites ci-dessous. La première utilise une expréssion régulière pour retrouver les adresses dans le texte fournit par le formulaire. Celle-ci se contente de reprendre les adresses ayant un nom de domaine comprenant une extension de 2 à 4 caractères et il existe sans doute des expréssions régulières aux critères plus exhaustifs.

function extract_emails( $str ){
    $regexp = '/([a-z0-9_\.\-])+\@(([a-z0-9\-])+\.)+([a-z0-9]{2,4})+/i';
    preg_match_all($regexp, $str, $m);
 
    return isset($m[0]) ? $m[0] : array();    
}

La fonction filter_emails, elle, permet de définir les adresses que l’on ne souhaite pas filtrer comme celle provenant de son hébergeur. Vous pourriez éventuellement y insérer une requête SQL pour y ajouter d’autres adresses.

function filter_emails( $email )
{
    $filters = array('monnomdedomaine.com', 'ovh.net');
 
    foreach( $filters as $filter ) {
        return strpos($email, $filter) === false;
    }
     
    return true;
}

Pour afficher les adresses déjà enregistrées dans votre DB vous pourriez utiliser un affichage comme celui ci et ajouter à titre d’exercice un formulaire qui vous permettra de retirer une adresse à travers une requête « DELETE … WHERE email = … ».

$db->query('SELECT email, date_fail FROM email_failures ORDER BY email' );
$emails = $db->fetch_all();
 
echo "Actuellement dans la base de données:";
 
echo "<p>";
 
echo "<table>";
foreach( $emails as $email ) {
        echo "<tr><td>" . $email['email'] ."</td><td>" . $email['date_fail'] . "</td></tr>";
}
echo "</table>";
 
echo "</p>";

– James Poulson.