Envoyer des messages avec fichiers joints


Thème

Il s'agit de parvenir à joindre un fichier aux messages créés et envoyés par la fonction mail() de PHP.
Deux scripts sont présentés, le premier est le prolongement de la solution détaillée dans ce document.
Le second utilise une classe mime_mail.class distribuée sous licence GPL et disponible sur le site www.phpteam.net.

Solution commentée

<!--fichier mail-pj.php-->
<?
$self="mail-pj.php";
$envoi=$_POST['envoi'];
$destinataire=$_POST['destinataire'];
$expediteur=$_POST['expediteur'];
$sujet=$_POST['sujet'];
$message=$_POST['message'];

if (! isset($envoi)) {
echo "
<H3 align='center'>Envoi de messages par PHP</H1>
<form method='post' action='mail.php' ENCTYPE='multipart/form-data'>
<table border=0 width=80% cellspacing=3 cellpadding=3  bgcolor='#ebebeb' align='center'><tr>
<td> Destinataire </td>
<td><input type=text name='destinataire' size=30 value=''></td>
</tr><tr>
<td> Expéditeur </td>
<td><input type=text name='expediteur' size=30 value=''></td>
</tr><tr>
<td> Sujet </td>
<td><input type=text name='sujet' value=''></td>
</tr><tr>
<td> Texte du message </td>
<td><textarea rows=10 cols=50 name='message' value=''></textarea></td>
</tr><tr>
<td> Fichier joint </td>
<td><input type=file name='joint' value='Choisir'></td>
</tr><tr>
<td>Validation : </td>
<td><input type='submit' name='envoi' value='Envoyer'></td>
</tr></table>
</form>
";
}
else {
/* pour neutraliser les \ ajoutés à la transmission devant les ' et les " */
$saisie=stripslashes($saisie);
$sujet=stripslashes($sujet);

/* partie générale de l'en-tête
 ******************************/
 $entete  = "From: $expediteur\r\n";
 $entete .= "Reply-To: $expediteur\r\n";
 $entete .= "MIME-Version: 1.0\r\n";
 $entete .= "X-Mailer: PHP\r\n";

/******************************
 * Cas ajout d'un fichier joint
 ******************************/
if ( ! empty($joint)) {
 $fich= $_FILES['joint']['tmp_name'];
 $taille = $_FILES['joint']['size'];
 $type = $_FILES['joint']['type'];
 $nom = $_FILES['joint']['name'];

// ajout d'un texte à la saisie
 $message .= "\r\nNB Ajout d'une pièce jointe : $nom\r\n";
// ouverture du fichier joint uploadé en lecture
 $f = fopen($fich, "r") or die("ouverture du fichier $fich impossible ...");
// récupération du code du fichier joint
 $code =fread($f, $taille);
// encodage standard
 $code = chunk_split(base64_encode($code));

 /* dans le cas de l'envoi d'un fichier joint
 * il convient de séparer le corps du message du fichier
 * pour cela on utilise un identifiant de séparateur
 *******************************************************/
// identifiant de séparateur, en principe unique
 $limite = md5(uniqid(time() ));

/* composition de l'en-tête du message :
 * le message textuel suivi du code du fichier
 *********************************************/
 $entete .= "Content-Type: multipart/mixed;boundary=$limite\r\n\r\n";

 $entete .= "--$limite\r\n";
 $entete .= "Content-type:text/plain;charset=us-ascii\r\n";
 $entete .= "Content-transfer-encoding:8bit\r\n\r\n";
 $entete .= "$message\r\n";

 $entete .= "--$limite\r\n";
 $entete .= "Content-type:$type;name=$nom\r\n";
 $entete .= "Content-transfer-encoding:base64\r\n\r\n";
 $entete .= "$code\r\n";
 $entete .= "--$limite--";

 /**************************
 * envoi du message AVEC pj
 ***************************/
 $ok=mail($destinataire, $sujet,"",$entete);
}

else {

 /**************************
 * envoi du message SANS pj
 ***************************/
  $ok=mail($destinataire, $sujet,$message,$entete);
}

// message de compte-rendu de la fonction mail
if ($ok)
  echo "Envoi réussi !";
else
  echo "L'envoi a échoué ..";
}
?>

Utilisation de la classe mime_mail

Voir le source de cette classe qui contient en commentaire un petit mode d'emploi.
Voici un exemple très simple pour montrer la syntaxe à mettre en oeuvre pour utiliser cette classe (ici, le fichier joint est supposé placé dans le même répertoire que le script).

<?
require "mime_mail.class.php";

// création d'un objet de la classe
$mail = new mime_mail();

// fixer l'adresse de réception
$mail->to = "xxx.yyy@zzz.fr";
// préciser le sujet
$mail->subject = "A bientôt ? ";
// le texte (corps) du message
$mail->body = "Je t'envoie une photo de nos merveilleuses vacances ..";
// fixer l'adresse de l'expéditeur (optionnel)
$mail->from = "uuu.vvv@www.fr";
// en-têtes optionnels
$mail->headers = "Date: 01/09/2004";

// récupérer le contenu du fichier
$nomfich="maphoto.png";
$f = fopen($nomfich,"r") or die("ouverture du fichier $fich impossible ...");
$code = fread($f, filesize($nomfich));
fclose($f);
// et l'attacher au message
$mail->attach($code, $nomfich);

// envoyer !
$mail->send();
?>