Script PHP permettant de se connecter à un serveur de messagerie via IMAP

  • sudo apt-get install php-imap
  • Editer le fichier php.ini et insérer la directive : extension=imap
  • sudo service apache2 restart

Explications

  1. Connexion au serveur IMAP :

    • La fonction imap_open établit une connexion au serveur en utilisant vos informations d'identification.
  2. Recherche d'emails :

    • La fonction imap_search accepte des critères pour rechercher des emails :
      • ALL : Tous les emails.
      • UNSEEN : Emails non lus.
      • FROM "expediteur@example.com" : Emails provenant d'une adresse spécifique.
      • SINCE "01-Jan-2024" : Emails reçus après une date spécifique.
  3. Récupération des en-têtes :

    • La fonction imap_headerinfo retourne des informations comme le sujet, l'expéditeur, la date, etc.
  4. Lecture du corps de l'email :

    • La fonction imap_body récupère le contenu du message.
    • L'option FT_PEEK empêche de marquer l'email comme lu.
  5. Décodage des sujets :

    • Utilisez imap_utf8 pour décoder les sujets encodés dans des formats comme UTF-8 ou MIME.
  6. Gestion des erreurs :

    • Vérifiez toujours les retours des fonctions IMAP et utilisez imap_last_error pour afficher les erreurs si nécessaire.

Critères IMAP courants pour imap_search

  • Non lus : 'UNSEEN'
  • Depuis une date : 'SINCE "01-Jan-2024"'
  • Avant une date : 'BEFORE "01-Jan-2024"'
  • Par expéditeur : 'FROM "expediteur@example.com"'
  • Par destinataire : 'TO "destinataire@example.com"'
  • Avec mot-clé dans l'objet : 'SUBJECT "mot-clé"'

Améliorations possibles

  • Gestion des pièces jointes : Vous pouvez utiliser imap_fetchstructure pour analyser les parties MIME et récupérer les pièces jointes.
  • Pagination des emails : Si vous avez beaucoup de messages, il est utile de paginer les résultats.
  • Marquer comme lu : Supprimez FT_PEEK pour marquer les emails comme lus.


Explications

  1. Analyser la structure MIME :

    • La fonction imap_fetchstructure retourne la structure complète du message, y compris les différentes parties MIME (texte, HTML, pièces jointes).
    • Les pièces jointes sont identifiables par leur disposition MIME (ex. attachment ou inline).
  2. Vérification des parties MIME :

    • Chaque partie peut avoir des métadonnées comme dparameters contenant le nom du fichier.
    • La disposition attachment ou inline indique souvent une pièce jointe.
  3. Récupérer les données de la pièce jointe :

    • Les données de la pièce jointe sont récupérées avec imap_fetchbody.
    • Les encodages courants sont :
      • Base64 (3) : Utilisez base64_decode pour décoder.
      • Quoted-printable (4) : Utilisez quoted_printable_decode.
  4. Sauvegarde locale :

    • Utilisez file_put_contents pour enregistrer les pièces jointes dans un répertoire local.

Cas spéciaux

  1. Emails sans pièces jointes :

    • Certains emails peuvent ne contenir que du texte ou des images intégrées sans disposition attachment. Vous pouvez aussi vérifier inline si nécessaire.
  2. Structure complexe :

    • Si un email a des sous-parties (comme des fichiers compressés), parcourez récursivement les sous-parties en vérifiant chaque niveau.

Améliorations possibles

  • Créer un répertoire pour chaque email : Organisez les pièces jointes dans des sous-dossiers basés sur l'identifiant du message.
  • Gérer les noms de fichiers en conflit : Ajoutez des horodatages ou des suffixes uniques aux noms de fichiers.
  • Filtrer par type MIME : Récupérez uniquement certains types de fichiers (PDF, images, etc.).

Le code :

<?php

// Informations de connexion
$server = '{imap.exemple.com:993/imap/ssl}'; // Serveur IMAP avec SSL
$username = 'votre_adresse_email@example.com'; // Adresse email
$password = 'votre_mot_de_passe'; // Mot de passe du compte

// Connexion au serveur IMAP
$mailbox = imap_open($server, $username, $password);

if (!$mailbox) {
    die("Connexion échouée : " . imap_last_error());
}

echo "Connexion réussie au serveur IMAP.\n";

// Récupérer les identifiants des emails non lus
$emails = imap_search($mailbox, 'UNSEEN');

if (!$emails) {
    echo "Aucun message trouvé.\n";
} else {
    // Trier les emails par ordre décroissant
    rsort($emails);

    foreach ($emails as $emailId) {
        echo "\n--- Analyse de l'email ID : $emailId ---\n";

        // Récupérer la structure du message
        $structure = imap_fetchstructure($mailbox, $emailId);

        if (isset($structure->parts) && count($structure->parts)) {
            for ($i = 0; $i < count($structure->parts); $i++) {
                $part = $structure->parts[$i];

                // Vérifier si la partie est une pièce jointe
                if (isset($part->disposition) && strtolower($part->disposition) === 'attachment') {
                    // Récupérer le nom du fichier
                    $filename = '';
                    if (!empty($part->dparameters)) {
                        foreach ($part->dparameters as $param) {
                            if (strtolower($param->attribute) === 'filename') {
                                $filename = imap_utf8($param->value);
                            }
                        }
                    }

                    // Si le fichier n'a pas de nom, ignorer
                    if (!$filename) {
                        continue;
                    }

                    // Récupérer le contenu de la pièce jointe
                    $attachment = imap_fetchbody($mailbox, $emailId, $i + 1); // Les parties sont indexées à partir de 1
                    if ($part->encoding == 3) { // Base64
                        $attachment = base64_decode($attachment);
                    } elseif ($part->encoding == 4) { // Quoted-printable
                        $attachment = quoted_printable_decode($attachment);
                    }

                    // Sauvegarder la pièce jointe localement
                    $savePath = __DIR__ . "/$filename";
                    file_put_contents($savePath, $attachment);
                    echo "Pièce jointe sauvegardée : $savePath\n";
                }
            }
        } else {
            echo "Pas de pièces jointes trouvées.\n";
        }
    }
}

// Fermer la connexion IMAP
imap_close($mailbox);

?>