Voyons maintenant comment joindre un fichier dans un e-mail.
Changement de l'en-tête
Bon, comme je vous l'ai déjà expliqué dans les précédentes parties, lorsque l'on souhaite envoyer un e-mail en texte et en HTML, on doit déclarer dans le
header le
Content-Type :
multipart/alternative.
Ça, c'était pour du texte et du HTML. Pour pouvoir joindre un fichier, cela va changer un petit peu.

En effet, le
Content-Type :
multipart/alternative prévient le client qu'il va recevoir du texte et du HTML, mais pas un ou plusieurs fichiers. Pour cela, on va utiliser le
Content-Type :
multipart/mixed qui, lui, prévient juste le client qu'il va recevoir plusieurs parties différentes.
Maintenant, après les modifications, votre
header devrait ressembler à cela :
Code : PHP | <?php
//=====Création du header de l'e-mail.
$header = "From: \"WeaponsB\"<weaponsb@mail.fr>".$passage_ligne;
$header .= "Reply-to: \"WeaponsB\" <weaponsb@mail.fr>".$passage_ligne;
$header .= "MIME-Version: 1.0".$passage_ligne;
$header .= "Content-Type: multipart/mixed;".$passage_ligne." boundary=\"$boundary\"".$passage_ligne;
//==========
?>
|
Maintenant, avant d'aller plus loin, il va nous falloir comprendre ce qu'est réellement un fichier.
Citation : Définition d'un fichierUn fichier est en fait une suite de caractères. Ces caractères sont par la suite interprétés par le logiciel que vous utilisez pour l'ouvrir.
Je pense que, maintenant, vous avez compris comment nous allons procéder pour joindre un fichier à un e-mail.
Il va donc nous falloir lire le contenu du fichier pour, par la suite, l'ajouter dans le courriel.
Comme mon tutoriel ne porte pas sur la gestion de fichier en PHP, je vais juste vous donner le code que j'utilise pour lire les fichiers joints à mes e-mails.
Code : PHP | <?php
$fichier = fopen("image.jpg", "r"); //on ouvre le fichier en lecture seule.
$attachement = fread($fichier, filesize("image.jpg")); //on lit l'ensemble du fichier avec la fonction fread.
fclose($fichier); //on ferme le fichier.
?>
|
Maintenant que nous avons le contenu de notre fichier, nous allons devoir l'encoder en 64 bits.
Whaouu !! Encoder ? C'est quoi, ça ? Moi je n'y connais rien en codage !
Pas de problème. Encoder, c'est remplacer un caractère ou une suite de caractères par un ou une autre.
Comment encoder un fichier en 64 bits ? Grâce au PHP, rien de plus simple ! En effet, il existe une fonction qui fait ça tout seul. C'est pas beau, ça ?
Il s'agit de la fonction
base64_encode(), que l'on va utiliser comme ceci :
Code : PHP | <?php
$attachement = chunk_split(base64_encode($attachement));
?>
|
Au passage, vous remarquerez que j'ai également utilisé la fonction
chunk_split(), qui sert, lorsqu'elle n'a pas de second argument, à effectuer un retour à la ligne tous les 76 caractères, ce qui permet de respecter la norme
RFC 2045.
Voilà. Maintenant que nous avons notre fichier dans une variable et qu'il est au bon format, on va pouvoir l'ajouter à notre e-mail.
Pour l'ajouter, on va faire comme lorsque l'on voulait déclarer soit du texte, soit du HTML.
La déclaration se voit quand même quelque peu enrichie. On va devoir maintenant déclarer :
- le nom du fichier ;
- Content-Disposition: XXXXXX; filename="Nom_du_fichier".
Le
Content-Disposition permet de dire que ce qui suit devra être en fichier joint. Pour cela, on lui donnera la valeur
attachment.
Ce qui, en code, nous donnera :
Code : PHP | <?php
$message.= "Content-Disposition: attachment; filename=\"nom_fichier\"".$passage_ligne;
?>
|
Le
Content-Type va lui aussi changer. En effet, rappelez-vous, c'est lui qui détermine à quoi correspondent les caractères entre les deux
boundary. Le problème dans le cas présent, c'est que le
Content-Type dépendra du fichier que vous voulez joindre.

Il faudra donc le faire varier en fonction de l'extension du fichier que vous envoyez. Ces types sont définis par l'
IANA. Vous trouverez
ici une liste non exhaustive des différents types disponibles, avec descriptions.
Comme dans cet exemple, nous allons joindre le fichier
image.jpg et nous allons utiliser le
Content-Type: image/jpeg. Lors de la déclaration d'un
Content-Type qui sert à joindre un fichier, on doit aussi déclarer le nom du fichier joint. Au final, nous obtiendrons une déclaration du
Content-Type similaire à celle-ci :
Code : PHP | <?php
$message.= "Content-Type: image/jpeg; name=\"nom_fichier\"".$passage_ligne;
?>
|
Maintenant que nous avons vu les différentes étapes, je vous donne la déclaration que vous devriez avoir obtenue si vous m'avez bien suivi.
Code : PHP | <?php
$message.= "Content-Type: image/jpeg; name=\"image.jpg\"".$passage_ligne;
$message.= "Content-Transfer-Encoding: base64".$passage_ligne;
$message.= "Content-Disposition: attachment; filename=\"image.jpg\"".$passage_ligne;
?>
|
Bon, maintenant, vous pensez que l'on va pouvoir directement envoyer le fichier joint ? Eh bien non.

Évidemment, cela aurait été trop simple. Car si jamais vous essayez d'insérer directement votre fichier joint dans le courriel, la personne qui va le recevoir aura un e-mail avec ce schéma :
- e-mail en texte,
- e-mail en HTML,
- pièce jointe.
Ce problème est dû au changement du
Content-Type : multipart/mixed. Pour résoudre ce problème, on va devoir déclarer à nouveau un
Content-Type : et une autre
boundary. Pour vous expliquer le mieux possible, je vais vous faire une comparaison entre le schéma actuel et le schéma final.
Citation : Schéma actuelOuverture boundary.
Déclaration de type (exemple texte).
Texte.
Ouverture boundary.
Déclaration de type (exemple HTML).
HTML.
Fermeture boundary.
Fermeture boundary.
Citation : Schéma finalOuverture boundary.
Déclaration du nouveau content-type et de la seconde boundary.
Ouverture boundary_2.
Déclaration de type (exemple texte).
Texte.
Ouverture boundary_2.
Déclaration de type (exemple HTML).
HTML.
Fermeture boundary_2.
Ouverture boundary.
Déclaration de la pièce jointe.
Fermeture boundary.
Voilà pour finir le code final.
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76 | <?php
$mail = 'weaponsb@mail.fr'; // Déclaration de l'adresse de destination.
if (!preg_match("#^[a-z0-9._-]+@(hotmail|live|msn).[a-z]{2,4}$#", $mail)) // On filtre les serveurs qui présentent des bogues.
{
$passage_ligne = "\r\n";
}
else
{
$passage_ligne = "\n";
}
//=====Déclaration des messages au format texte et au format HTML.
$message_txt = "Salut à tous, voici un e-mail envoyé par un script PHP.";
$message_html = "<html><head></head><body><b>Salut à tous</b>, voici un e-mail envoyé par un <i>script PHP</i>.</body></html>";
//==========
//=====Lecture et mise en forme de la pièce jointe.
$fichier = fopen("image.jpg", "r");
$attachement = fread($fichier, filesize("image.jpg"));
$attachement = chunk_split(base64_encode($attachement));
fclose($fichier);
//==========
//=====Création de la boundary.
$boundary = "-----=".md5(rand());
$boundary_alt = "-----=".md5(rand());
//==========
//=====Définition du sujet.
$sujet = "Hey mon ami !";
//=========
//=====Création du header de l'e-mail.
$header = "From: \"WeaponsB\"<weaponsb@mail.fr>".$passage_ligne;
$header.= "Reply-to: \"WeaponsB\" <weaponsb@mail.fr>".$passage_ligne;
$header.= "MIME-Version: 1.0".$passage_ligne;
$header.= "Content-Type: multipart/mixed;".$passage_ligne." boundary=\"$boundary\"".$passage_ligne;
//==========
//=====Création du message.
$message = $passage_ligne."--".$boundary.$passage_ligne;
$message.= "Content-Type: multipart/alternative;".$passage_ligne." boundary=\"$boundary_alt\"".$passage_ligne;
$message.= $passage_ligne."--".$boundary_alt.$passage_ligne;
//=====Ajout du message au format texte.
$message.= "Content-Type: text/plain; charset=\"ISO-8859-1\"".$passage_ligne;
$message.= "Content-Transfer-Encoding: 8bit".$passage_ligne;
$message.= $passage_ligne.$message_txt.$passage_ligne;
//==========
$message.= $passage_ligne."--".$boundary_alt.$passage_ligne;
//=====Ajout du message au format HTML.
$message.= "Content-Type: text/html; charset=\"ISO-8859-1\"".$passage_ligne;
$message.= "Content-Transfer-Encoding: 8bit".$passage_ligne;
$message.= $passage_ligne.$message_html.$passage_ligne;
//==========
//=====On ferme la boundary alternative.
$message.= $passage_ligne."--".$boundary_alt."--".$passage_ligne;
//==========
$message.= $passage_ligne."--".$boundary.$passage_ligne;
//=====Ajout de la pièce jointe.
$message.= "Content-Type: image/jpeg; name=\"image.jpg\"".$passage_ligne;
$message.= "Content-Transfer-Encoding: base64".$passage_ligne;
$message.= "Content-Disposition: attachment; filename=\"image.jpg\"".$passage_ligne;
$message.= $passage_ligne.$attachement.$passage_ligne.$passage_ligne;
$message.= $passage_ligne."--".$boundary."--".$passage_ligne;
//==========
//=====Envoi de l'e-mail.
mail($mail,$sujet,$message,$header);
//==========
?>
|