vendredi 30 août 2013

[TUTO] PHP - Mail + pièce jointe

Une fonction plutôt capricieuse.

Mail(), voilà une fonction qui en a déjà agacé plus d'un! Le moindre pet de travers et nous voilà partis pour déboguer à l'aveugle.

Vous trouverez ci-dessous un code simple pour envoyer un mail en php avec une pièce jointe. Testé et approuvé sur Windows Xampp et Linux. Attention aux utilisateurs Xampp, il faudra (dans certains cas) configurer sendmail au préalable.


Le code

$mail_to = "xxx@xxx.fr"; //Destinataire
$from_mail = "xxx@yyy.com"; //Expediteur
$from_name = "Nom"; //Votre nom, ou nom du site
$reply_to = "xxx@yyy.com"; //Adresse de réponse
$subject = "Objet du mail";    
$file_name = "piece_jointe.pdf";
$path = $_SERVER['DOCUMENT_ROOT']."/fichiers";
$typepiecejointe = filetype($path.$file_name);
$data = chunk_split( base64_encode(file_get_contents($path.$file_name)) );
//Génération du séparateur
$boundary = md5(uniqid(time()));
$entete = "From: $from_mail \n";
$entete .= "Reply-to: $from_mail \n";
$entete .= "X-Priority: 1 \n";
$entete .= "MIME-Version: 1.0 \n";
$entete .= "Content-Type: multipart/mixed; boundary=\"$boundary\" \n";
$entete .= " \n";
$message  = "--$boundary \n";
$message .= "Content-Type: text/html; charset=\"iso-8859-1\" \n";
$message .= "Content-Transfer-Encoding:8bit \n";
$message .= "\n";
$message .= "Bonjour,<br />Veuillez trouver ci-joint le bon de commande<br/>Cordialement";
$message .= "\n";
$message .= "--$boundary \n";
$message .= "Content-Type: $typepiecejointe; name=\"$file_name\" \n";
$message .= "Content-Transfer-Encoding: base64 \n";
$message .= "Content-Disposition: attachment; filename=\"$file_name\" \n";
$message .= "\n";
$message .= $data."\n";
$message .= "\n";
$message .= "--".$boundary."--";
mail($mail_to, $subject, $message, $entete);

\n ou \r\n ????


Après être tombé sur un paquet de site internet, la plupart disent qu'un simple \n ne peut fonctionner et préconisent systématiquement des \r\n en fin de ligne. Pour ma part, la plupart des codes proposés sur les tutos ne fonctionnaient pas.

Le séparateur


Vous remarquerez qu'on a un séparateur ($boundary). Ici, c'est une sorte de clé aléatoire que l'on va générer en début de code et utiliser pour découper notre mail en trois parties : les en-têtes - le message - la pièce jointe.
Il est important d'utiliser les tirets (--) dans le séparateur comme je l'ai fait ci-dessus. Attention au séparateur de fin : si vous oubliez les derniers tirets (comme beaucoup de gens) vous risquez de voir votre mail en pièce jointe ATT00001 (0ko). J'ai bien précisé "vous risquez", effectivement, d'une boite mail à l'autre le résultat peut changer. Un \n absent, une mauvaise syntaxe risque très souvent de vous foirer votre mail sans pour autant vous en avertir avec des erreurs PHP