Email avec pièce jointe en PHP

Envoyer des fichiers grâce à la fonction mail.

16 mars 2017

Envoyer un mail en PHP est globalement assez simple grâce à la fonction mail. Il est en revanche plus compliqué d'ajouter une pièce jointe. Le corps du mail doit ainsi respecter une structure très particulière dont les blocs sont délimités par des chaînes de caractères : les frontières. Nous aurons besoin de 2 frontières : la première pour délimiter les différentes parties du mail (message et pièce-jointe), la seconde pour délimiter les alternatives du message (HTML ou texte brut).

Envoyer un fichier par mail en PHP

<?php
$to = 'foo@bar.com';
$from = 'baz@toto.com';
$subject = 'Mail avec fichier';
$message_html = '<b>Test</b>';
$file_content = 'hello';

$boundary_structure = md5(rand());
$boundary_alternatives = md5(rand());

$headers = [
        "From: $from",
        "Reply-To: $from",
        "Content-Type: multipart/mixed; boundary=\"$boundary_structure\""
];

/* Encodage du contenu du fichier à envoyer. En accord avec la RFC 2045. */
$attachment = chunk_split(base64_encode($file_content));

/* Le mieux serait d'inclure un fichier de template mais pour l'exemple un ob_start fera l'affaire. */
ob_start();
?>
--<?=$boundary_structure . PHP_EOL /* Première partie de la structure: le message */?>
Content-Type: multipart/alternative; boundary="<?=$boundary_alternatives?>"

--<?=$boundary_alternatives . PHP_EOL /* Première alternative: plain text */?>
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 8bit

<?=strip_tags($message_html)?>

--<?=$boundary_alternatives . PHP_EOL /* Seconde alternative: HTML */?>
Content-Type: text/html; charset="utf-8"
Content-Transfer-Encoding: 8bit

<?=$message_html?>

--<?=$boundary_alternatives /* Fin des alternatives */?>--

--<?=$boundary_structure . PHP_EOL /* Seconde partie de la structure: le fichier */?>
Content-Type: text/csv; name="nom_fichier.csv"
Content-Transfer-Encoding: base64
Content-Disposition: attachment

<?=$attachment?>

--<?=$boundary_structure /* Ferme la structure */?>--
<?php
$message = ob_get_clean();

$is_mail_sent = mail($to, $subject, $message, implode(PHP_EOL, $headers));

A bientôt !

Par
Créateur et administrateur.

Dans la même catégorie

Formater un tableau pour CURLOPT_POSTFIELDS
PHP : modifier les attributs privés d'un objet
Tester l'existence d'un fichier dans l'include path
Convertir récursivement un objet PHP en tableau
PHP : formater un tableau en CSV
Comment envoyer un mail en ligne de commande ?
RSYNC : Comment synchroniser des fichiers à travers une connexion ssh ?
Exécuter un code PHP en ligne de commande
Doctrine 2 : générer les classes PHP depuis la base de données
Comment catcher les erreurs en PHP ?
Doctrine 2 : comment afficher la requête SQL ?
Comment construire une URL sans caractères spéciaux en PHP ?
Comment lister les fichiers PHP inclus sur ma page ?
Les fonctions anonymes récursives en PHP
Requête HTTP asynchrone en PHP
La résolution statique à la volée ou Late Static Bindings
Trouver les jours fériés français en PHP
Comment allumer son ordinateur à distance en PHP ?
Comment utiliser la balise meta viewport ?
Une version mobile de mon site avec le Zend Framework
Doctrine et le Zend Framework : Présentation, intégration et utilisation
Créer son flux RSS simplement avec Zend_Feed
Appliquer un layout sur un mail avec le Zend Framework
Comment lancer une requête multi-bases avec les fonctions MySQL ?
Implode / Explode : Du tableau à la chaine de caractères, de la chaine de caractères au tableau

Commentaire(s)