Formulaire PHP et envoi par email

I. Introduction à l'envoi par email de formulaire PHP

Vous avez été nombreux à réagir et à me demander des extensions des précédents tutoriaux concernant les formulaires PHP, et cela fait toujours plaisir que vous portiez un si grand intérêt à nos tutoriaux. Dans le précédent tutoriel, je vous expliquais comment réaliser un formulaire PHP, HTML, CSS et envoyer les données du formulaire dans une base de données MySQL.
Sur votre demande, nous allons maintenant voir comment envoyer ces mêmes données par email. Pour cela, nous allons utiliser le même formulaire que précedemment, mais la différence est que vous allez recevoir les données entrées par un utilisateur sur votre adresse email et non dans une base de données.
N'hésitez pas à vous reporter aux précédents tutoriaux pour la création préalable du formulaire dont nous allons nous servir ici : la partie Formulaire HTML et la partie Formulaire CSS.

II. Explications

1. Ajouter un champ email sur le formulaire

Nous allons supposer que si vous vous envoyez par email les données du formulaire de votre site, vous avez besoin de l'adresse email de l'internaute pour éventuellement lui répondre. Je n'avais pas inclut ce champ dans le formulaire HTML du tutoriel précédent, cela va nous faire l'occasion de voir comment ajouter un champ de texte par le code HTML.
Nous allons ajouter le champ Adresse email par exemple entre le champ Ville et le champ Pays. Voyez le code à ajouter en gras ci-dessous :

<label>Ville : </label>
<input type="text" name="ville" size="30" /><br />
<label>Adresse email : </label>
<input type="text" name="email" size="30" /><br />
<label>Pays : </label>
<select name="pays">
  <option value="france">France</option>
  <option value="belgique">Belgique</option>
  <option value="suisse">Suisse</option>
</select>

Je ne réexplique pas d'où vient ce code, pour cela voyez le tutoriel pour Faire un formulaire HTML, CSS, PHP (1 sur 3).
Voici le résultat que vous obtiendrez après l'ajout de ce champ :

formulaire php et envoi par email image 1

2. Le fichier de traitement PHP du formulaire

2-1. Définitions et vérification des champs

Nous allons maintenant créer un nouveau fichier traitement.php qui enverra le formulaire tout comme dans le tutoriel précédent, sauf que vous allez le modifier en conséquence pour pouvoir envoyer les données par email.

Comme pour le précédent tutoriel, commencez par définir quelques message d'erreurs ou confirmation qui s'afficheront à l'internaute :

$msg_erreur = "Erreur. Les champs suivants doivent être obligatoirement 
remplis :<br/><br/>";
$msg_ok = "Votre demande a bien été prise en compte.";
$message = $msg_erreur;

Puis nous allons définir le destinataire de l'email qui vous sera envoyé et contenant les informations du formulaire rempli. Remplacez donc l'adresse email par la vôtre.
Entrez également un sujet pour l'email que vous recevrez du formulaire. Sur cet exemple j'ai mis comme sujet "Message du formulaire de example.com".

define('MAIL_DESTINATAIRE','[email protected]'); // remplacer par votre email
define('MAIL_SUJET','Message du formulaire de example.com');

Ensuite vient la vérification des champs du formulaire, pour s'assurer qu'ils ne sont pas laisser vides. Là encore c'est pareil que le tutoriel précédent, vous pouvez juste ajouter l'obligation d'entrer une adresse email dans ce nouveau champ que nous avons introduit :

// vérification des champs
if (empty($_POST['civilite'])) 
$message .= "Votre civilité<br/>";
if (empty($_POST['nom'])) 
$message .= "Votre nom<br/>";
if (empty($_POST['adresse'])) 
$message .= "Votre adresse<br/>";
if (empty($_POST['codepostal'])) 
$message .= "Votre code postal<br/>";
if (empty($_POST['ville'])) 
$message .= "Votre ville<br/>";
if (empty($_POST['email'])) 
$message .= "Votre adresse mail<br/>";
if (empty($_POST['comments'])) 
$message .= "Votre message<br/>";

2-2. Préparation des données

Si l'utilisateur n'a pas remplit correctement un des champs obligatoires, il vous faudra commencer par lui afficher le message d'erreur. Mais comment allons-nous savoir si c'est le cas ? Et bien c'est là que vous allez voir l'intérêt de la variable $message , elle sert à conserver la variable $msg_erreur intacte afin de faire une comparaison. L'idée est la suivante : "si le contenu de la variable $message et plus grand que celui de la variable $msg_erreur, c'est que nous venons d'ajouter des champs non remplis", et cela implique d'afficher l'erreur.

NB : nous aurions pu aussi revérifier que tous les champs obligatoires ne sont pas vides pour faire la même chose, mais cela va faire beaucoup d'appels à la fonction empty() que l'on peut éviter. Voilà ce que cela donne :

if (strlen($message) > strlen($msg_erreur)) {
  echo $message; die();
}

Par contre si les champs sont bien remplis, nous allons commencer par récupérer chaque clé du tableau $_POST pour en faire des variables à l'aide de $$ tout en nettoyant les espaces dé début et fin inutiles avec trim() ainsi que les éventuels slashes ajoutés aux variables $_POST pour la sécurité, avec stripslashes.
NB : dans le tutoriel précédent nous utilisions mysql_real_escape_string() mais notez que cela est uniquement pour protéger les donnéesavant insertion MySQL. Or nous n'utilisons plus MySQL dans ce tutoriel.


foreach($_POST as $index => $valeur) {
  $$index = stripslashes(trim($valeur));
}

Puis pour ne rien changer, nous allons encore concaténer les centres d'intérêts cochés en liste séparée par des virgules :

$interets = $_POST['interets'];
$sqlinterets = '';
for ($i=0; $i<count($interets); $i++)
{
  $sqlinterets .= $interets[$i];
  $sqlinterets .= ', ';
}

2-3 Envoi de l'email

Pour finir, nous allons procéder à l'envoi de l'email, afin que vous réceptionniez les données du formulaire rempli par l'utilisateur. Commençons par préparer l'en-tête du mail qui va notamment permettre de spécifier l'adresse email de la personne qui envoie le formulaire afin de pouvoir lui répondre, le type d'encodage etc. Connaître toutes les en-têtes pour l'envoi d'un email est purement technique et inutile la plupart du temps car en général c'est votre client mail qui se charge de tout cela lorsque vous envoyez un mail.

//Préparation de l'entête du mail:
$mail_entete  = "MIME-Version: 1.0\r\n";
$mail_entete .= "From: {$_POST['nom']} "
             ."<{$_POST['email']}>\r\n";
$mail_entete .= 'Reply-To: '.$_POST['email']."\r\n";
$mail_entete .= 'Content-Type: text/plain; charset="iso-8859-1"';
$mail_entete .= "\r\nContent-Transfer-Encoding: 8bit\r\n";
$mail_entete .= 'X-Mailer:PHP/' . phpversion()."\r\n";

Préparons également le corps du mail que vous allez recevoir. Nous allons spécifier de qui vient le message, l'adresse complète de la personne, ses centres d'intérêts et le message facultatif. De cette façon vous recevez toutes les données entrées sur le formulaire créé.

// préparation du corps du mail
$mail_corps  = "Message de : $civilite $nom\n";
$mail_corps .= "Adresse : $adresse, $codepostal $ville, $pays\n";
$mail_corps .= "Ses centres d'intérêts : $sqlinterets\n\n\n";
$mail_corps .= $comments;

Enfin il va falloir envoyer le mail avec la fonction PHP mail() qui prend en paramètre un destinataire, un sujet, le corps et l'en-tête. Si le mail est bien envoyé, la fonction retourne "TRUE", et nous affichons le message.
Dans le cas contraire, si la fonction retourne FALSE, nous affichons un message d'erreur.

// envoi du mail
if (mail(MAIL_DESTINATAIRE,MAIL_SUJET,$mail_corps,$mail_entete)) {
  //Le mail est bien expédié
  echo $msg_ok;
} else {
  //Le mail n'a pas été expédié
  echo "Une erreur est survenue lors de l'envoi du formulaire par email";
}

}

Voilà, si je rempli le formulaire avec les données de l'image en 1., j'obtiendrai ce message dans ma boîte email :

formulaire php et envoi par email image 1

3. Le code final de traitement.php

Voici enfin le code entier du fichier traitement.php que nous venons de voir, permettant d'envoyer les données du formulaire par email :

<?php
$msg_erreur = "Erreur. Les champs suivants doivent être obligatoirement 
remplis :<br/><br/>";
$msg_ok = "Votre demande a bien été prise en compte.";
$message = $msg_erreur;
define('MAIL_DESTINATAIRE','[email protected]'); // remplacer par votre email
define('MAIL_SUJET','Message du formulaire de example.com');

// vérification des champs
if (empty($_POST['civilite'])) 
$message .= "Votre civilité<br/>";
if (empty($_POST['nom'])) 
$message .= "Votre nom<br/>";
if (empty($_POST['adresse'])) 
$message .= "Votre adresse<br/>";
if (empty($_POST['codepostal'])) 
$message .= "Votre code postal<br/>";
if (empty($_POST['ville'])) 
$message .= "Votre ville<br/>";
if (empty($_POST['comments'])) 
$message .= "Votre message<br/>";

// si un champ est vide, on affiche le message d'erreur et on stoppe le script
if (strlen($message) > strlen($msg_erreur)) {
   echo $message; die();
}

// sinon c'est ok => on continue
foreach($_POST as $index => $valeur) {
  $$index = stripslashes(trim($valeur));
}

$interets = $_POST['interets'];
$sqlinterets = '';
for ($i=0; $i<count($interets); $i++)
{
  $sqlinterets .= $interets[$i];
  $sqlinterets .= ', ';
}

//Préparation de l'entête du mail:
$mail_entete  = "MIME-Version: 1.0\r\n";
$mail_entete .= "From: {$_POST['nom']} "
             ."<{$_POST['email']}>\r\n";
$mail_entete .= 'Reply-To: '.$_POST['email']."\r\n";
$mail_entete .= 'Content-Type: text/plain; charset="iso-8859-1"';
$mail_entete .= "\r\nContent-Transfer-Encoding: 8bit\r\n";
$mail_entete .= 'X-Mailer:PHP/' . phpversion()."\r\n";

// préparation du corps du mail
$mail_corps  = "Message de : $civilite $nom\n";
$mail_corps .= "Adresse : $adresse, $codepostal $ville, $pays\n";
$mail_corps .= "Ses centres d'intérêts : $sqlinterets\n\n\n";
$mail_corps .= $comments;

// envoi du mail
if (mail(MAIL_DESTINATAIRE,MAIL_SUJET,$mail_corps,$mail_entete)) {
  //Le mail est bien expédié
  echo $msg_ok;
} else {
  //Le mail n'a pas été expédié
  echo "Une erreur est survenue lors de l'envoi du formulaire par email";
}

?>

4. Erreur fréquente

Attention, l'envoi des données du formulaire est réalisée par la fonction PHP mail() comme vous venez de le voir. Il faut donc que PHP soit bien configuré pour pouvoir envoyer des mails avec un serveur mail, sinon ça fonctionnera pas.
Pour que la fonction mail() soit disponible, il faut que PHP ait accès au service sendmail sur le serveur, au moment de la compilation. Si vous utilisez un autre programme de mail, comme qmail ou postfix, assurez-vous d'utiliser les bonnes API. PHP va commencer à chercher sendmail dans votre PATH, puis, dans les dossiers suivants : /usr/bin:/usr/sbin:/usr/etc:/etc:/usr/ucblib:/usr/lib. Il est hautement recommandé d'avoir sendmail de disponible dans votre PATH. De plus, l'utilisateur qui compile PHP doit avoir le droit d'accéder à l'exécutable sendmail.

En général lorsque vous faites le test sur un serveur apache windows installé avec easyphp ou encore WAMP, vous pouvez avoir le problème car il n'y a pas de serveur mail actif sur un Windows XP par défaut. Vous risquez donc d'avoir une erreur comme celle-ci :

Warning: mail() [function.mail]: SMTP server response: 502 negative vibes in C:\Program Files\wamp\www\formulaire\email.php on line 60
Une erreur est survenue lors du formulaire par email

Toutefois si vous testez le même script chez la plupart des hébergeurs de sites web, cela fonctionnera car ils sont en général configurés pour que la fonction mail() fonctionne avec un serveur mail installé. Donc pas de panique...

III. Conclusion du tutorial

Après le précédents tutoriaux sur l'élaboration complète d'un formulaire et l'envoi de données dans une base de données MySQL, voici donc de quoi satisfaire les personnes qui souhaitent faire la même chose mais en s'envoyant les données par email à la place de MySQL. Le prochain tutoriel vous montrera même comment combiner les deux, et ainsi envoyer les données du formulaire par email + dans une base de données MySQL.
Si vous avez tout suivi, les formulaires HTML / CSS / PHP ne doivent plus avoir beaucoup de secrets pour vous :-)

J'espère que vous aurez appris des choses à l'issu des ces tutoriaux, et si vous avez des questions, je vous répondrai avec plaisir sur le forum.