Php, générer un e-mail avec plusieurs pièces jointes.

E-mailVoici une fonction pour envoyer un e-mail en PHP avec des pièces jointes quelque soit leur extension (ou presque).

La machine qui m’a servi à faire les tests est un champs MX du domaine, et l’adresse de l’expéditeur appartient au domaine (ça aide.)

Le résultat des essais:

  • Vers une boite e-mail free -> OK
  • Vers une boite e-mail du travail (c’est un postfix maison) -> OK
  • Vers une boite hotmail -> OK
  • Vers une boite aol: ça passe dans les spam
  • Vers une boite gmail -> OK

Plusieurs façons de fournir les pièces jointes sont possibles. les explications sont données au deuxième bloc de commentaire.

L’écriture de ce script a été possible grace à un tutoriel du site du zéro qui m’a bien servi de support.

Voici quelques exemples d’utilisation (qui m’ont servi pour les tests):

//on post files
  SendEmailwidthJoin($_POST['messageTXT'],$_POST['messageHTML'],$_POST['destinataire'],$_POST['expediteur'],$_FILES,$_POST['objet']);
  // on array files
  SendEmailwidthJoin($_POST['messageTXT'],$_POST['messageHTML'],$_POST['destinataire'],$_POST['expediteur'],array('/var/www/AAPC.doc','/var/www/consultation.doc'),$_POST['objet']);
  //juste un string
 SendEmailwidthJoin($_POST['messageTXT'],$_POST['messageHTML'],$_POST['destinataire'],$_POST['expediteur'],'/var/www/AAPC.doc',$_POST['objet']);

Voici la function:

<?php
function FilePathToArray($leFichier)
{
      if (!file_exists($leFichier)){
	return false;
      }
      $AboutTheFile=pathinfo($leFichier);
      return array(
	'chemin'	=> $leFichier,
	'nom'	=> $AboutTheFile['filename'],
	'extension'=>$AboutTheFile['extension'],
	'mimeType'=> mime_content_type($leFichier),// mime_content_type est une function obsolète (je sais), mais bien pratique.
	'contenu'	=> chunk_split(base64_encode(file_get_contents($leFichier)))	//ounch les ressources
      );

}
function SendEmailwidthJoin($message_txt,$message_html,$destinataire,$expediteur,$fichiersAJoindre,$objet,$replyTo="" )
{
  /*
  * Envoie un e-mail "propre"  avec des pièces jointes
  *
  * Codé par gnieark https://blog-du-grouik.tinad.fr février 2012
  * Distribué sans aucune garantie dans les conditions établies là  https://blog-du-grouik.tinad.fr/pages/Mentions-l%C3%A9gales
  *
  * Vous ne devez pas supprimer ce bloc de commentaires.
  *
  * La création de ce code est en tres grande partie basée sur le tutoriel de Weaponsb qui a sévi sur le site du zéro:
  * "Envoyer un e-mail en PHP" http://www.siteduzero.com/tutoriel-3-35146-e-mail-envoyer-un-e-mail-en-php.html
  * 
  */

  /*
  *	*** How to use this function ***
  *	$fichiersAJoindre peut être:
  *		- un  string contenant le chemin vers un seul fichier
  *		- un array sous la forme array('Chemin/Vers/Fichier1.ext','/chemin/vers/fichiers2', etc...);
  *		- un array structuré comme la super variable globale PHP $_FILES:
  *			$array('file1'	=> array('
  *				  'name'     => ,
  *				  'type'     => ,
  *				  'tmp_name' => ,
  *				  'error'    => ,
  *				  'size'     => ),
  *			      'file2' => array(
  *				    (..)etc)
  *			)
  *		/!\ Aucune vérification sur du directory transversal n'est faite au niveau de cette function.
  *		En cas de variables fournies par l'utilisateur, prenez le soin de protéger en amont de cette function.
  *	$message_txt (obligatoire contient le message au format txt)
  *	$message_html facultatif (envoyez une string vide "" si vous ne souhaitez pas envoyer votre message en html) 
  *	$destinataire : 'nom@fai.com' ou '"Nom Prenom<nom@fai.com>"' ou '"Nom1 Prenom1<nom1@fai.com>,Nom2 Prenom2<nom2@fai.com>"'
  *	$expediteur: idem
  *	$replyTo: facultatif, si différent de l'expéditeur.
  */


   //=== vérifier et préparer les pieces jointes:
  $arrayFiles=array();
  if (is_string($fichiersAJoindre)){
    $lesFichiers[]= FilePathToArray($fichiersAJoindre);
  }
  if (is_array($fichiersAJoindre)){
    //tester si c'est du type $_FILES
    if ((isset($fichiersAJoindre[0])) AND (is_string($fichiersAJoindre[0])) ){
      //un array simple avec des strings 
      foreach($fichiersAJoindre as $stringFile){
	$lesFichiers[]= FilePathToArray($stringFile);
      }
    }else{
	//de type $_FILES
	foreach($fichiersAJoindre as $arrayFiles){
	  $aboutFile=pathinfo($arrayFiles['name']);
	  $lesFichiers[]=array(
	    	'chemin'	=> getenv('TMP')."/".$arrayFiles['tmp_name'],
		'nom'	=> $aboutFile['filename'],
		'extension'=>$aboutFile['extension'],
		'mimeType'=> mime_content_type(getenv('TMP')."/".$arrayFiles['tmp_name']),// mime_content_type est une function obsolète (je sais), mais bien pratique.
		'contenu'	=> chunk_split(base64_encode(file_get_contents($arrayFiles['tmp_name'])))	//ounch les ressources
	  );
	}
    }
  }


  //===générer les délimiteurs dans l'email ===
  do{
    $leRand=md5(rand());
    $boundary = "-----=".$leRand;
  }while(!strpos($message_txt.$message_html, $leRand) === false); // oui, la vérification là , c'est du zèle.

  do{
    $leRand=md5(rand());
    $boundary_alt = "-----=".md5(rand());
    $isOK=true;
    foreach($lesFichiers as $fichier){
      if(!strpos($fichier['contenu'], $leRand) === false){
	$isOK=false;
      }
    }
  }while($isOK==false);//là  en plus d'etre du zele, ça bouffe les ressources

  //=== le type de retour à la ligne ===
  if (!preg_match("#^[a-z0-9._-]+@(hotmail|live|msn).[a-z]{2,4}$#", $destinataire)){
    $passage_ligne = "\r\n";
  }else{
    $passage_ligne = "\n";
  }
  
  //=== header ===
  $headers ="From: ".$expediteur.$passage_ligne;
  if ($replyTo==""){
    $headers.= "Reply-to: ".$expediteur.$passage_ligne;
  }else{
    $headers.= "Reply-to: ".$replyTo.$passage_ligne;
  }
  
  $headers.= "MIME-Version: 1.0".$passage_ligne;
  $headers.= "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;

  //=====Ajout du message au format texte.
  if ($message_txt!=""){
    $message.= $passage_ligne."--".$boundary_alt.$passage_ligne;
    $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;
  }
  //==========
  
  //=====Ajout du message au format HTML.
  if ($message_html!=""){
    $message.= $passage_ligne."--".$boundary_alt.$passage_ligne;
    $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;
  }
  //==========

  //pièces jointes
  foreach($lesFichiers as $fileArray)
  {
    $message.= $passage_ligne."--".$boundary.$passage_ligne;
   
    $message.="Content-Type: ".$fileArray['mimeType']."; name="".$fileArray['nom'].".".$fileArray['extension'].""".$passage_ligne;
    $message.="Content-Transfer-Encoding: base64".$passage_ligne;
    $message.="Content-Disposition: attachment; filename="".$fileArray['nom'].".".$fileArray['extension'].""".$passage_ligne;
    $message.= $passage_ligne.$fileArray['contenu'].$passage_ligne.$passage_ligne;
  }
  $message.= $passage_ligne."--".$boundary."--".$passage_ligne; 
  //echo $message;
  //Envoi du mail
  mail($destinataire, $objet, $message, $headers);
}
?>

l’icone "e-mail" en en tête de ce billet provient du site economie-numerique.net

Ajouter un commentaire

Les commentaires peuvent être formatés en utilisant une syntaxe wiki simplifiée.

La discussion continue ailleurs

URL de rétrolien : https://blog-du-grouik.tinad.fr/trackback/711

Fil des commentaires de ce billet

Page top