PHP : Envoyer des mails en HTML et avec des pièces jointes

La fonction mail de PHP est majoritairement utilisée pour envoyer du texte simple ou parfois du HTML quand l’utilisateur maitrise les Content-type. Cependant, elle nous permet un nombre de choses incroyable ! A vrai dire, on peut faire pareil que n’importe quel client mail, car, c’est nous qui choisissons ce que l’on met dans la source…

Le HTML dans le mail

Le mail n’est pas réservé à un usage de texte simple, il nous permet (grâce aux webmails et clients de messagerie compatible) d’afficher du HTML dans le corps du mail.

Cependant, c’est la même histoire que pour l’encodage des pages web (cf: Le problème d’encodage : Des accents en points d’intérrogation) sauf qu’en plus, – mais c’est très simple – il faut indiquer au client de messagerie quel sorte de message on lui envoi (texte brute, html, fichier binaire..).
Nous allons prendre un exemple où nous somme une société qui vend des stylos, on commence par un simple mail :

Dans ce cas, le client va recevoir un mail en texte brut qui contiendras ce qu’on lui demande. Il resemblera à ça :

Bonjour,

Venez acheter des stylo chez VendeurDeStylo, des réduction à plus de -20% pour vous !

Et re-voilà les entêtes toujours là pour nous aider ! Afin de donner un peut plus de style à notre mail, nous pourrions lui ajouter du HTML ! Cependant, il faut indiquer au client mail que c’est du HTML et qu’il sorte ça trousse de détection correspondante !
C’est comme pour les pages web, il y a un système d’entête pour les mails !

Les entêtes

Dans le précédent article sur l’encodage des caractères, nous avons vu que les entêtes se définissaient soient par balise meta soit par la fonction header de PHP. Là, c’est aucun des deux !
Si vous êtes un peu observateur, vous êtes peut-être déjà aller sur la documentation de PHP pour voir la syntaxe de la fonction mail :

bool mail ( string $to , string $subject , string $message [, string $additional_headers [, string $additional_parameters ]] )

Ici, la documentation nous informe qu’il y a 5 arguments dont deux facultatifs ( entre crochets ). Nous utilisons uniquement les 3 obligatoires !
Si vous regarder la 4ème argument, il s’appelle $additional_headers se qui signifie entêtes supplémentaires.

C’est donc grâce à cet argument que nous allons passer nos entêtes. Ici, nous n’avons que l’entête Content-type à définir, et, c’est là, comme pour le Content-type des pages web…

$additional_headers

Reprenons notre code et ajoutons-y une variable $entetes qui contiendras toutes les entêtes supplémentaires. Nous devons mettre cette en-tête :

Content-Type: text/html; charset=”UTF-8″

Attention: Remplacez bien l’encodage des caractères (ici UTF-8) par celui dans lequel est encodé votre page contenant le code PHP ! (si vous avez du mal, n’hésitez pas à aller voir Le problème d’encodage : Des accents en points d’intérrogation)

Attention: N’oubliez pas “n” après chaque entête (et pas après tout le bloc des entêtes supplémentaires) et n’oubliez pas d’ajouter le 4ème argument de la fonction mail !

Maintenant, votre mail pourra contenir du HTML et il sera afficher sur l’ordinateur du client (si le client messagerie est compatible) !

Plus de retours à la ligne…

Si vous essayez d’envoyer le mail comme ça, vous aurez quelque chose du type :

Bonjour !Venez acheter des stylo chez VendeurDeStylo, des réduction à plus de -20% pour vous !

Ceci est du au fait que le client de messagerie n’interprète plus le message comme un texte banal mais comme du HTML, par conséquent, il ne tien plus compte des retours à la lignes “manuels” dans le code… Il faut soit utiliser des balises p pour faire des paragraphes soit utiliser des balises br pour faire des saut à la ligne avec le HTML.
Nous allons donc refaire notre mail en y ajoutant quelques petits effets de texte !

Et voilà un mail qui ressemble à ça :

Bonjour !

-20 % sur les stylos chez VendeurDeStylo

Venez acheter des stylo chez VendeurDeStylo, des réduction à plus de -20% pour vous !

Des pièces jointes !

Attention: C’est une deuxième partie, on recommence donc un nouveau code.

Maintenant, nous somme toujours notre entreprise de vente de stylos de nous voulons envoyer automatiquement par mail la facture PDF d’un client. (on admet que le fichier PDF est déjà créé)

Vous avez toujours utiliser le mail comme juste un espace de texte (brut ou html), cependant, il y a aussi un autre système qui permet de faire du mail une chose vraiment très puissante (et qu’utilisent pleinement les clients mails), c’est le principe de division de mail.
C’est-à-dire que le mail peut être coupé en deux pour pouvoir contenir plusieurs type d’objets (texte, html, fichier binaire…)

Le principe du boundary

Le découpage des mails en plusieurs parties se fait grace à un boundary, un séparateur en fait.
Chaque partie est séparée par celui-ci et chaque partie a ses propres entêtes

Determination du boundary

Le séparateur doit être du chaine de caractères que l’on ne trouve pas dans le mail (même s’il faut la préceder de “–“, ça peut quand même arriver…) sinon, il peut y avoir des gros problèmes lors de l’interprétation du mail par le client de messagerie de notre client.
C’est pourquoi, nous allons utiliser un petit système qui nous permettra de créer un code unique à chaque fois.

Une fois le boundary créé, il faut encore que nous disions au logiciel de messagerie du client que c’est un message en plusieurs parties !

Encore des entêtes

Pour bien continuer, nous allons refaire un tour avec les entêtes ! Cette fois-ci, il faut mettre ce Content-type :

Content-Type: multipart/mixed;
boundary=”LE BOUNDARY”

Si vous le vous rappelez plus vraiment comment faire, n’hésitez-pas à relire la première partie.
Voici donc le nouveau code :

Maintenant, il faut donc préparer le corps du message !

Le corps du message écartelé

Pour commencer chaque nouvelle partie du message, il faut passer à la ligne et ajouter “–” suivi du boundary. Après, on fait un retour à la ligne, on met les entetes de cette partie, on saute deux lignes et on met le contenu de la partie.
Voici un exemple de mail découpé :

Content-Type: multipart/mixed;
boundary=”————010606060607040509020301″

This is a multi-part message in MIME format.
————–010606060607040509020301
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit

Un autre message ouvert

————–010606060607040509020301
Content-Type: application/pdf; name=”fichier.pdf”
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename=”fichier.pdf”

JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0ZpbHRlci9GbGF0
ZURlY29kZT4+CnN0cmVhbQp4nL1bS4sruxHez6/wOjBz9ZYajGFmbAeyu8mBLIas8oKQE8jd
3L+fqlJJKnVL3faFEw74eLr1KNXjq5es3vTp15f/ntRJwTe/+Dd7Sk6/Ladf/n768+9O/8nv
4N8v/3z5+PaibYJ3MS6nb387/XTXJx1g3rd/fJ2dvmh3DvbyavHzL9/+8KJpIo5JbyZP+v7y
092USWelLt/+1YbFKIeJtaO92LNRl1dzDho3iP6ynGPCr/w40Ody8YWEdCl/e5phcEAeHBXM
5oXkY9yFFtLn6HhgeZlXCbf2gEbfcZfrRfOHroOCu5RJMXPj9u3l5xU3fXhLpwifzE570oYO

Voici une code source “guidé” :

Maintenant, on doit mettre le code source du fichier PDF encodé en base64 et formaté en RFC 2045 pour que tout soit conforme…
On va déjà récuperer la source de notre fichier avec file_get_contents :

Ensuite, l’encoder en base64 grâce à base64_encode :

Et mettre tout ça en forme grâce à la fonction chunk_split

Ce qui nous donne au final :

Et voila, on ferme le message en mettant le boundary entre deux “–“.
Votre client recevra votre PDF en pièce jointe.

Aller plus loin

Les autres entêtes

Il y a beaucoup d’entêtes et certaines peuvent être très utiles.

From

L’entête From permet d’afficher de qui est envoyé le message. Par exemple, vous envoyer un mail à partir d’un script PHP pour pouvez faire “croire” que vous l’envoyez depuis un logiciel de messagerie quelquonque :

From: Jacques Dupond

Reply-To

Demandez une réponse sur une autre adresse email, par exemple, votre adresse email de travail :

Reply-To: jacques.dupond@societe.fr

CC

Pour envoyer une copie conforme à quelqu’un d’autre, à votre comptable par exemple, rien de plus simple :

CC: comptable@masociete.fr

Compatibilité pour les clients mails ne supportant pas le HTML

Comme je l’ai sous-entendu, certains logiciels de messagerie ne supportent pas le HTML dans le corps des message, ce qui fait que les client peuvent voir des balises HTML, ce qui ne fait pas très pro !
C’est pourquoi, vous pouvez utiliser les boundary !

Faites deux parties :

  • Une avec le code en texte brute
    Content-type: text/plain
  • Une avec le code en HTML
    Content-type: text/html

Et, il n’y a plus aucun problème !

J’espère vous avoir aider.
Bon mail !

facebooktwittergoogle_plusredditpinterestlinkedinmail

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">