Envoyer un Email en UTF-8 avec la fonction mail() de PHP

D’une première approche il me paru simple d’envoyer des emails en UTF-8 mais j’ai fini par me rendre compte qu’il ne suffisait pas de changer l’encodage des caractères.
En effet, même s’il est défini pour utiliser l’UTF-8, le protocole email est un peu plus complexe que ça et requiert pour certains caractères spéciaux que les chaines soient encodées en quoted printable (ou Q/P), ce qui permet de maintenir une certaine compatibilité avec les vieux encodages de caractères.

Parmi mes soucis, les caractères spéciaux ne s’affichaient pas correctement dans le sujet et des caractères disparaissaient avec certains clients mail (comme Outlook), notamment avec l’attribut href en HTML, le lien était interprété mais il commençait par ttp:// au lieu de http:// et il ne menait à rien.
Ce qui est vicieux, c’est que ça fonctionne sous certains clients, parfois la majorité mais pas tous, car ça ne respectait pas entièrement les propriétés d’encodage du protocole mail.

Revoyons les base d’un email en UTF-8 ensemble:

  • S’il ne possède pas plusieurs contenus*, il doit contenir l’entête suivante:
    Content-Type: text/plain; charset="UTF-8"
  • S’il possède plusieurs contenus*, ce sont les entêtes des contenus concernés qui doivent être déclarées comme ceci.
    Les entêtes de contenu sont déclarés en dessous le boundary, le séparateur de contenu.

*Un email peut contenir une version texte et une version html pour, par exemple, maintenir une compatibilité avec les clients n’interprétant pas le HTML.

Maintenant, passons aux choses sérieuses… Le sujet.
Par défaut, le sujet ne peut pas simplement être passé en UTF-8 et il ne suit pas les règles définie dans les entêtes, notamment celle de l’encodage.
Voici comment devrait être formaté votre sujet:

quoted_printable_encode() est une fonction native de PHP vous permettant d’encoder la chaîne (UTF-8) en quoted printable (imap_8bit fait à peu près la même chose mais nécessite une bibliothèque).
Le reste permet de dire que le sujet a un encodage spécial qui est l’UTF-8 en quoted printable.
Votre sujet ne ressemble plus à rien mais il est efficacement interprété par la majorité des clients mail.

Non, ce n’est pas tout, il nous reste le problème des liens dans le corps des mails, notamment en HTML.
Le corps d’un email HTML doit être lui aussi une chaîne quoted printable, il vous suffit donc d’appliquer dessus la fonction quoted_printable_encode() précédemment citée. Pour l’exemple, cela remplacera les = par =3D, permettant à n’importe quel client mail de comprendre qu’il s’agit en fait d’un = (un caractère spécial pour le protocole email).

Si vous continuez à rencontrer des soucis avec l’encodage de vos mails, c’est que vous ne les envoyez pas en l’UTF-8, vérifiez l’encodage de vos fichiers, de votre base de données et de votre connexion à la base de données.
Cela se remarquera par le fait que les caractères existent et que ce qui sera affiché à la place sera valide mais, ce seront les mauvais caractères, comme des caractères chinois.

Florent

Je suis un développeur web à mon compte et je m'intéresse à beaucoup de choses en informatique...

Aucun commentaire

Commenter