Stop aux pop-up sauvages, indiquant que tel ou tel champ n'a pas été renseigné correctement, via une vérification javascript. Il est très facile de concevoir un formulaire entièrement géré par des instructions PHP. On fait juste appel à la récursivité : le script se traite lui même par rechargement de la page, en utilisant la variable prédéfinie super globale fr2.php.net/variables.predefined $_POST transmise par le serveur. Aussi, comme cette variable contient un tableau complet des données de formulaire, ce dernier est modifiable sans nécessairement modifier le code PHP (ajout de champs à volonté).
Pour commencer, voyez la feuille de styles dev.ppan.net/webdev_form.css spécifique qui compose ce formulaire. Ensuite, copiez le code commenté ci-dessous ou téléchargez l'archive zip. Le nom de fichier est sans importance, car le formulaire s'appelle lui-même via la variable prédéfinie $_SERVER['PHP_SELF'] (c'est ré-cur-sif !).
Ce type de méthode, côté serveur, implique un rechargement de page à chaque erreur. Certains contestent ce principe en défendant la vérification javascript, mais quid du javascript quand il est désactivé ?...
Vous pouvez tester ce formulaire. Comme je suis un garçon bien élevé je ne mettrai pas votre email dans une quelconque mailing-liste. Au pire, mettez un téléphone spatial et pas d'email, il partira tout de même !
Pourquoi certaines fichiers ne passent pas ?
La limite d'upload par défaut (php.ini) est fixée à 2 Mo
mais elle dépend de l'hébergeur et peut être bien moindre.
Pourquoi le script n'envoie rien ?
Vérifier que la fonction mail() est disponible chez
l'hébergeur.
Pourquoi le champ de fichier n'est pas visible ?
Il faut créer le répertoire upload sur le serveur.
S'il porte un autre nom, modifier la variable $rep (pour la racine
$rep='/')
Comment limiter la pièce jointe à un type de fichier ?
Il faut tester $mimetype. Exemple pour un type image :
if(!stristr($mimetype,'image')) {
$erreur = "Seulement un fichier de type image SVP";
$focus = 7;
}
Comment créer ou supprimer un champ ?
Tout fonctionne par couple vérification (PHP) et champ (HTML) correspondant.
En cas de compréhension difficile du PHP, contentez vous d'ajouter la
partie HTML (mais sans vérification).
<?
# code PHP
if (empty($_POST['foo'])) {
$erreur = "Merci de renseigner Champ";
$focus = 30; // chaque champ a sa propre valeur $focus
}
?>
<!-- code html -->
<p><label for="foo">Champ</label>
<input id="foo"<? if($focus == 30) echo " class='focus'";?> name="foo" value="<?= htmlentities($_POST['foo'],ENT_QUOTES)?>"></p>
Pourquoi la page ne se redirige pas après traitement du formulaire ?
Le code PHP ci-dessous doit impérativement être placé avant tout code HTML. Ceci est dû à la fonction header() qui gère l'envoi d'en-tête HTTP et doit s'exécuter avant toute sortie (un caractère quelconque avant la première balise <?php est considéré comme tel).
<?php
error_reporting (E_ERROR | E_WARNING | E_PARSE);
/*
Envoi de formulaire sans javascript avec pièce jointe proposé par Pierre Pesty http://dev.ppan.net/
Variables A MODIFIER selon vos besoins :
*/
# remplacez login@fai par votre email
$destinataire = "login@fai";
# nom et titre de page
$pageName = "Formulaire de contact";
# en-tête de l'objet du mail (option: vide)
$entete = "[dev.ppan.net]";
# envoi en copie carbone (option: vide)
$email_cc = "";
# envoi en copie cachée (option: vide)
$email_bcc = "";
# emplacement de la feuille de styles
$cssform = "webdev_form.css";
# nom du répertoire pour upload des pièces jointes
# le répertoire (ici "upload") doit être créé sur le serveur
$rep = "upload/"; // ne pas oublier le slash /
# taille max de la pièce jointe (multiple de 1024)
$taillemax = 204800;
# menu déroulant pour l'objet (option: vide)
# ajout d'option : 'n'=>'Choix 1', 'n+1'=>'Choix 2', etc.
# la première ligne (optionnelle) impose un choix
$objets = array(
0 => 'Choisissez',
1 => 'Test du script',
2 => 'Ce script',
3 => 'Autre',
);
# page vers laquelle rediriger le script après envoi réussi
$pageconfirme = "index.php";
/*
si $pageconfirme n'est pas dédiée aux messages on peut y traiter
la variable $_GET['mailOK'] comme ceci :
if(isset($_GET['mailOK']))
echo "Votre message a été envoyé";
*/
/*
fin des modifications
*/
$erreur = false;
$message = false;
$focus = 0;
# l'utilisateur a validé le formulaire
if (!empty($_POST)) {
# vérification des champs requis (Nom, Objet, Message, Email ou Tel)
if (empty($_POST['Message'])) {
$erreur = "Merci de renseigner le message";
$focus = 1; // modification couleur du champ de saisie concerné
}
if (empty($_POST['Objet'])) {
$erreur = "Merci de renseigner l'objet";
$focus = 2;
}
if (empty($_POST['Nom'])) {
$erreur = "Merci de renseigner votre nom";
$focus = 3;
}
# email et tel sont vides : pas glop !
if (empty($_POST['Email']) && empty($_POST['Tel'])) {
$erreur = "Saisir email et/ou téléphone SVP";
$focus = 4;
}
# vérification de l'email non vide
elseif (!empty($_POST['Email'])) {
if(!preg_match('`^[[:alnum:]]([-_.]?[[:alnum:]])*@[[:alnum:]]([-_.]?[[:alnum:]])*\.([a-z]{2,4})$`',$_POST['Email'])) {
$erreur = "Email non conforme";
$_POST['Email'] = "";
$focus = 5;
}
# vérification du téléphone (sans espaces)
} elseif (!is_numeric(str_replace(" ","",$_POST['Tel']))) {
$erreur = "Téléphone non conforme";
$_POST['Tel'] = "";
$focus = 6;
}
# pièce jointe (nouveauté 12.10.2005)
$piecejointe = "";
if(!$erreur && strlen($_FILES['Fichier']['name'])) {
$fichier = $_FILES['Fichier'];
# upload du fichier sur le serveur
$temp = $fichier['tmp_name'];
$name = $fichier['name'];
$size = $fichier['size'];
$destination = $rep.$name;
if($size > $taillemax)
$erreur = "Taille du fichier $name > ".(int)($taillemax/1024)." Ko";
elseif(!@is_uploaded_file($temp))
$erreur = "Téléchargement du fichier $name impossible";
elseif(!@move_uploaded_file($temp, $destination))
$erreur = "Problème de transfert du fichier $name";
if($erreur) $focus = 7;
else {
# lecture du type de fichier
if(!function_exists('mime_content_type')) {
function mime_content_type($fichier) {
# ajouter autant de combinaisons que souhaitées
$mime = array(
'.gif' => 'image/gif',
'.jpg' => 'image/jpeg',
'.psd' => 'image/x-xwd',
'.png' => 'image/png',
'.txt' => 'text/plain',
'.doc' => 'application/msword',
'.xls' => 'application/vnd.ms-excel',
);
# par défaut
if(!$type = $mime[strrchr($fichier,'.')]) $type = "application/octet-stream";
return $type;
}
}
/*
pour utiliser mime_content_type()
éditer le fichier php.ini et enlever le commentaire sur :
extension=php_mime_magic.dll
sous Windows ajouter ces 2 lignes :
mime_magic.debug = On
mime_magic.magicfile = "c:\chemin_du_fichier\magic.mime"
NB : fonction non activée chez OVH
*/
$mimetype = mime_content_type($destination);
# lecture et conversion du fichier
if($openf = @fopen($destination, "rb")) {
$fichier = fread($openf, filesize($destination));
@fclose($openf);
# encodage norme RFC 2045
$piecejointe = chunk_split(base64_encode($fichier));
} else {
$erreur = "Problème de lecture du fichier $name";
$focus = 7;
}
}
}
# pas d'erreur donc on continue
if(!$erreur) {
# traitement du tableau $_POST qui contient les paires name => value
$message_final = "";
foreach($_POST as $key => $value) {
# la boucle passe les champs vides ou non désirés
# pour passer d'autres champs les séparer par |
if (!strlen($value) || preg_match("/MAX_FILE_SIZE|Objet/i", $key)) continue;
$message_final .= "$key : ".strip_tags($value)."\n";
}
# formatage du message de confirmation affiché (option)
# conversion des sauts de ligne et des caractères spéciaux
$message = nl2br(htmlentities($message_final));
# si $objets est un tableau : Objet = select donc index = $_POST['Objet']
if(is_array($objets))
$objet = "$entete ".$objets[$_POST['Objet']];
# sinon Objet = input donc en français dans le texte !
else
$objet = "$entete ".$_POST['Objet'];
# si l'email n'est pas renseigné on le remplace par celui
# du destinataire, en ajoutant une alerte au message
$final_mail = $_POST['Email'];
if(empty($_POST['Email'])) {
$final_mail = $destinataire;
$message_final .= "\nNe pas répondre par mail : email absent.\n";
}
# en-têtes
$headers = "From: ".$final_mail;
if(strlen($email_cc))
$headers .= "\nCC: ".$email_cc;
if(strlen($email_bcc))
$headers .= "\nBCC: ".$email_bcc;
# hôte expéditeur
$message_final .= "Hôte : ".gethostbyaddr($_SERVER['REMOTE_ADDR']);
# si pièce jointe on ajoute l'en-tête spécifique avec séparateurs
if(strlen($piecejointe)) {
$boundary = "/-------".md5(uniqid(rand()))."-------/"; // séparateur
$headers .= "\nMIME-Version: 1.0\nContent-Type: multipart/mixed; boundary=\"$boundary\"\n";
$message_final =
"This is a multi-part message in MIME format.\n--$boundary\n".
"Content-Type: text/plain; charset=ISO-8859-1\n".
"Content-Transfer-Encoding: 7bit\n\n".
"$message_final\n\n--$boundary\n".
"Content-Type: $mimetype; name=\"$name\"\n".
"Content-Transfer-Encoding: base64\n".
"Content-Disposition: attachment; filename=\"$name\"\n\n".
"$piecejointe\n--".
$boundary."--\n";
}
# envoi du mail
if (@mail($destinataire, stripslashes($objet), stripslashes($message_final), $headers)) {
@unlink($destination); // suppression de la pièce jointe
# si la page de redirection est renseignée
if(!empty($pageconfirme)) {
@header("Location: ".$pageconfirme."?mailOK=1");
exit;
}
} else {
$pageName = "Echec !";
$erreur = "Echec de l'envoi ! Merci d'essayer encore";
}
} else {
$pageName = "Erreur de saisie !";
} // if(!$erreur)
} // if ($_POST)
?>
Voir les options d'upload pour parfaire le contrôle du fichier et la protection anti-spam éventuellement.
Ci-après, on note la présence de la fonction htmlentities dans chacun des champs de formulaire. Outre l'affichage universel de caractères accentués ou spéciaux, elle a deux objectifs : éviter le hack via des instructions type javascript (qui s'exécuteraient en cas d'erreur, au rechargement de page) et, via la constante ENT_QUOTES, recharger les post-données avec apostrophe (quote) incompatible avec les champs input.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title><? echo $pageName?></title>
<meta name="author" content="Pierre Pesty">
<meta name="generator" content="http://dev.ppan.net/">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link href="<? echo $cssform?>" type="text/css" rel="stylesheet">
</head>
<body>
<div>
<? if (!$erreur) { ?>
<h4>Contact</h4>
<p>Merci de renseigner les champs marqués d'un astérisque (email et/ou téléphone)</p>
<? } else { ?>
<p class="alerte"><? echo $erreur?></p>
<? } ?>
<hr>
<form name="formulaire" action="<? echo $_SERVER['PHP_SELF']?>" method="post" enctype="multipart/form-data">
<p>
<label for="nom">Nom</label><input id="nom" <? if($focus == 3) echo "class=\"focus\"";?> name="Nom" maxlength="30" value="<? echo htmlentities($_POST['Nom'], ENT_QUOTES)?>">
</p>
<p>
<label for="email">Email</label><input id="email" <? if($focus == 5 || $focus == 4) echo "class=\"focus\"";?> name="Email" maxlength="60" value="<? echo htmlentities($_POST['Email'], ENT_QUOTES)?>">
</p>
<p>
<label for="tel">Téléphone</label><input id="tel" <? if($focus == 6 || $focus == 4) echo "class=\"focus\"";?> name="Tel" maxlength="20" value="<? echo htmlentities($_POST['Tel'])?>">
</p>
<p>
<? if (is_array($objets)) { ?>
<label for="objet">Objet</label><select name='Objet' <? if($focus == 2) echo "class=\"focus\"";?> id="objet">
<?
foreach($objets as $key => $val) {
echo " <option value='$key'";
// vérifier si une des entrées a été choisie
if($key == $_POST['Objet']) echo " selected";
echo ">$val\n";
}
?>
</select>
<? } else { ?>
<label for="objet">Objet</label><input id="objet" <? if($focus == 2) echo "class=\"focus\"";?> name="Objet" maxlength="60" value="<? echo htmlentities($_POST['Objet'], ENT_QUOTES)?>">
<? } ?>
</p>
<p>
<label for="message">Message</label><textarea <? if($focus == 1) echo "class=\"focus\"";?> id="message" name="Message"><? echo htmlentities(stripslashes($_POST['Message']))?></textarea>
</p>
<? if (file_exists($rep)) { ?>
<p>
<label for="fichier">Pièce jointe</label><input type="hidden" name="MAX_FILE_SIZE" value="<? echo $taillemax?>"><input type="file" id="fichier" <? if($focus == 7) echo "class=\"focus\"";?> name="Fichier" size="35">
</p>
<p>
<label> </label>NB : taille du fichier inférieure à <?= (int)($taillemax/1024)?> Ko
</p>
<? } ?>
<p>
<label> </label><input id="submit" type="submit" value="Envoyer"> <a href="./">Accueil</a>
</p>
</form>
</div>
</body>
</html>
Plutôt que de recevoir la pièce jointe, pourquoi ne pas la lire en ligne ? Tout se passe dans la partie traitement (PHP). Pour cela on a d'abord besoin, dans les variables, de l'URL du site où sera stockée la pièce jointe :
# répertoire temporaire d'upload (option: vide ou $rep inconnu) $rep = "upload/"; // ne pas oublier le slash / # URL absolue où se trouve le répertoire $monsite = "http://dev.ppan.net/"; // ne pas oublier le slash /
Puis, au lieu de coder le fichier joint et l'envoyer, on le garde sur le serveur pour lecture ultérieure. Cependant, pour éviter les noms identiques, donc un écrasement, on lui attribue alors un nom codé :
$piecejointe = "";
if(!$erreur && strlen($_FILES['Fichier']['name'])) {
$fichier = $_FILES['Fichier'];
$name = $fichier['name'];
$temp = $fichier['tmp_name'];
$size = $fichier['size'];
# séquence de caractères
$chars = array(
"a","A","b","B","c","C","d","D","e","E","f","F","g","G","h","H",
"i","I","j","J","k","K","l","L","m","M","n","N","o","O","p","P",
"q","Q","r","R","s","S","t","T","u","U","v","V","w","W","x","X",
"y","Y","z","Z","1","2","3","4","5","6","7","8","9","0");
$max_elements = count($chars) - 1;
# composition du nom de fichier aléatoire (8 caractères)
for($i=0; $i<8; $i++) $aleatoire .= $chars[rand(0,$max_elements)];
# extraction de l'extension du fichier original
$extension = strtolower(substr(strrchr($name, "."), 1));
# attribution du nom de fichier sur le serveur
$newname = $aleatoire.".".$extension;
$destination = $rep.$newname;
# upload du fichier sur le serveur
if($size > $taillemax)
$erreur = "Taille du fichier $name > ".(int)($taillemax/1024)." Ko";
elseif(!@is_uploaded_file($temp))
$erreur = "Téléchargement du fichier $name impossible";
elseif(!@move_uploaded_file($temp, $destination))
$erreur = "Problème de transfert du fichier $name";
if($erreur) $focus = 7;
else $piecejointe = $monsite.$destination;
}
Enfin on ajoute au mail l'URL absolue du fichier téléchargé :
if(strlen($piecejointe)) {
# si pièce jointe on ajoute au mail un lien vers le fichier
$message_final .= "\nDocument joint : $piecejointe";
# on ajoute également un lien de suppression
$message_final .= "\nSupprimer : ".$monsite."supfichier.php?destination=".$destination;
}
$headers .= "\nMIME-Version: 1.0\nContent-Type: text/plain; charset=ISO-8859-1\nContent-Transfer-Encoding: 7bit\n";
Bien évidemment on supprime la ligne :
@unlink($destination); // suppression de la pièce jointe
Reste à créer un fichier supfichier.php qui se chargera de la destruction du fichier une fois lu, en deux lignes, afin d'éviter la gestion FTP du répertoire.
<?php
@unlink($_GET['destination']);
@header("Location: ./");
?>
Bonjour,
Merci pour cet excellent script, et pour votre gentillesse de le mettre à dispo de tous :-)
Pourriez-vous m'aider sur un point : je n'arrive pas à rendre le champs "envoi de pièce jointe" obligatoire...
Merci
Réponse du webmestre :
if (empty($_FILES['Fichier']['name'])) {
$erreur = "Merci de joindre un fichier";
}
Ajouter une vérification des autres champs via javascript, afin d'éviter le rechargement à chaque erreur.
Merci beaucoup pour ce script plein de commentaires et facile à adapter. Ca m'a fait gagner beaucoup de temps.
Bonjour, merci pour ce super formulaire.
cependant j'ai un léger problème quand je reçois le mail. en effet, toute est normal si mon formulaire est rempli avec une pièce jointe. Mais lorsque je ne joint pas de fichier la ponctuation dans le mail n'est pas prise en compte correctement. du type : é = é ; ô = ô... etc cela provient-il du charset? je suis passé en utf-8, mais rien ne change... pourriez vous me répondre svp?
Bonjour,
Merci pour ce script.
J'aurais besoin d'ajouter un bouton radio (type "votre choix : OUI ou NON"). Pourriez-vous m'indiquer la marche à suivre ?
Merci !
Réponse du webmestre :
Il suffit d'ajouter l'élément de formulaire name="Choix" avec pour value="oui" et "non". Le script traitera automatiquement son ajout dans le message.
Merci pour ce code.
J'ai un soucis, j'utilise le formulaire sur la home page d'un site en utilisant seulement deux champs (nom et email), j'ai pu faire les modifications de code sans soucis majeur.
Mon problème est que lorsque je reviens sur cette page, un message m'indique que le formulaire va de nouveau être envoyé et effectivement je reçois de nouveau un mail. Comment faire pour que le formulaire soit de nouveau vierge ou soit qu'aucun nouveau mail soit envoyé.
Merci d'avance et encore bravo. Et Meilleurs vœux pour cette nouvelle année.
Réponse du webmestre :
Afin d'éviter un F5 ou rafraîchissement de la page, il est conseillé d'utiliser la redirection de la page ($pageconfirme) en cas de succès. En revanche il est, à ma connaissance, impossible d'éviter un retour sur le formulaire (flèche navigateur) qui déclenche à nouveau la soumission des variables $_POST du formulaire.
Bonne année.
Bon je me joins à tous pour vous remercier et vous tirer mon chapeau...
Pour un pauvre graphiste peu doué en php comme moi... c'est génial...
Par contre j'ai un petit probleme... je n'arrive pas à configurer la page de redirection une fois le message envoyé.
Une fois le mail parti, la redirection ne se fait, on reste sur la même page (formulaire.php par exemple) et plus rien ne s'affiche.... lorsque je regarde le code source de la page d'ailleurs je me rend compte qu'il ne s'affiche que le début de ma page jusqu'à la partie php qui est alors supprimé.... en gros le code source est celui de la même page que le formulaire... et à partir du premier < ? plus rien ?!?...
Une idée ?
D'avance merci et encore bravo
Réponse du webmestre :
Vous devez renseigner
$pageconfirme = "index.php";
par la page ad hoc et y traiter la variable $_GET['mailOK']. Si la redirection header() ne fonctionne pas, c'est qu'il y a un bug quelque part.
NB : il est normal qu'aucun code PHP ne s'affiche puisqu'il est exécuté sur le serveur (chez l'hébergeur), qui ne renvoie (au "client") que le code HTML concerné.
Bonjour,
Merci pour cet article très complet, de loin le meilleur (et j'ai passé 1 jour 1/2 entier à visiter les forums de développeurs!).
J'aurais deux question svp à vous soumettre :
1- Comment faire pour ne récupérer que des fichiers PDF en pièce jointe ?
2- J'ai réussi à faire fonctionner correctement le script sur Gmail, mais pas avec OUTLOOK. Mon problème est que les emails doivent automatiquement arriver dans ce programme.
Merci par avance de votre réponse.
Réponse du webmestre :
1. avant la ligne "# pièce jointe" il faut ajouter un test de $_FILES['Fichier']['tmp_name'] en utilisant la fonction mime_content_type() ou finfo_file() qui doit retourner "application/pdf".
2. le script, exécuté sur un serveur web et utilisant la fonction mail() de PHP, n'a strictement rien à voir avec le logiciel qui réceptionne les mails. Par conséquent si le message parvient sur un compte Gmail, l'erreur sous Outlook vient d'ailleurs.
Mille merci !
Cela fait 15 jours que je cherchais ce type de formulaire qui fonctionne.
Si seulement j'avais trouvé votre code avant...
Je suis très très débutant en PHP et j'ai pourtant réussi du premier coup avec vos explications très claires.
J'aimerais tant être aussi doué mais bon.........
Encore merci et continuez SVP !
Ok j'ai finis par y parvenir!
Merci beaucoup :)
Idem pour moi.
Je planche la dessus depuis 2 semaines déjà et je ne parvient pas à ajouter des pièces jointes au mail.
Il y a forcement quelque chose qui m'échappe.
Réponse du webmestre :
Le problème d'upload multiple est de deux ordres : il faut traiter un tableau (champs sous la forme name="fichier[]" avec crochets) et savoir combien de pièces jointes devront être ajoutées. En HTML c'est un peu lourd car il faut un script (PHP ou javascript) qui ajoute autant de champs que l'utilisateur en demande. L'idéal est alors d'utiliser un applet Java : voir l'article "Upload multiple" sur ces ondes.
Bonjour,
Je suis très content d'être tombé sur ce tuto très bien fait et qui a le mérite d'être sérieusement réalisé.
Bravo donc !
Néanmoins, comme d'autres j'aimerais beaucoup que vous ajoutiez la méthode pour pouvoir ajouter d'autre pièces jointes...je sais que ça demande du temps et de la motivation mais de mon coté, je vous fais cette demande car ça fait des semaines que je planche sur ce "détails" et malgré des résultats approximatifs je n'ai toujours pas réussi à avoir trois pièces jointes inclues dans le mail envoyé...
Alors s'il vous plait: un petit effort supplémentaire serait vraiment bienvenu avec les lignes de codes complètes car parfois une indication qui vous semblera claire ne sera quand même pas suffisante pour les débutant comme moi.
Merci.
(C'est ça la rançon du succès... ;-) )
Réponse du webmestre :
Pour implémenter reCAPTCHA, il suffit d'ajouter ces lignes :
$resp = recaptcha_check_answer($privatekey, $_SERVER["REMOTE_ADDR"], $_POST["recaptcha_challenge_field"], $_POST["recaptcha_response_field"]);
if(!$resp->is_valid) { $erreur = "Réponse fausse ! (". $resp->error .")"; }
juste avant la ligne :
$piecejointe = "";
(je n'ai pas pris le temps de tester)
Bonjour,
Votre script est tout simplement formidable. J'aurais voulu avoir votre expertise pour savoir comment intégrer cet outil de Captcha qui est très bien lui aussi, à votre script. J'ai bien essayé mais le formulaire ne semble pas tenir compte du captcha lorsqu'il est validé...
Voici le captcha dont je parle : http://recaptcha.net/plugins/php/
Merci d'avance pour toute aide,
Thiéric
Script très propre, autant que je puisse en juger.
On arrive à le comprendre sans y connaître grand chose en php...
Mais quand même : que doit-on modifier pour qu'apparaissent en même temps tous les messages d'erreurs, et la coloration des champs respectifs, plutôt que l'un après l'autre ?
Merci pour la leçon.
Merci pour le partage.
bravo pour ce script très facile à utiliser, très efficace :) !! Merci de le partager !
Alors là, je ne dis qu'un seul mot : bravo ! !
Il ne me reste qu'à tester demain avec un fichier css et le contrôle anti-spam.
Merci à vous et à votre gentillesse d'avoir partagé ce code
bonjour
peut on modifier le code afin que le même message saisi par l'internaute lui soit renvoyé à l'adresse qu'il a indiqué ??
j'ai pensé à ça vu que beaucoup de serveurs gratuits tardent à envoyer le mail ou le supprime (pour contrer les spam) malgré une fonction mail activé (c'est le cas de 123.fr par exemple).
j'ai pensé à mettre une variable dans le champ Copie carbone les paramètres , celle ci correspondrait à la valeur inséré dans le champ mail.
que pensez vous ?? je m'y connait pas trop en la matière désolé si je dis des bétises
Réponse du webmestre :
Pour ajouter le mail au formulaire c'est très simple !
# en-têtes
$headers = "From: ".$final_mail;
if(!empty($_POST['Email']))
$headers .= "nCC: ".$_POST['Email'];
Bonjour,
Très bon script et surtout facile à installer.
Aidez-moi s'il vous plait à ajouter 2 fonctionnalités à mon formulaire:
1- Afficher les informations saisies sur la page (après avoir cliqué sur le bouton envoyer);
2- Envoyer un email de confirmation à ce celui qui a rempli le formulaire.
Merci
Réponse du webmestre :
Le point 1 n'est pas une bonne idée mais, à la place de
@unlink($destination);
@header("Location:".$pageconfirme."?mailOK=1");
exit;
on affiche $message_final sur la page.
Pour le point 2, il suffit d'ajouter sous
if (@mail($destinataire, stripslashes($objet), stripslashes($message_final), $headers))
ces deux lignes :
if(!empty($_POST['Email']))
@mail($_POST['Email'], stripslashes($objet), stripslashes($message_final), "From: ".$_POST['Email']);
(je n'ai pas ajouté de vérification)
Bonjour,
J'ai un petit souci... quand je mets l formulaire sur mon site/serveur la ligne permettant de sélectionner une pièce joint n'apparait plus... Que faire?
Merci pour ce script!
Réponse du webmestre :
Il faut créer le répertoire "upload" sur le serveur (racine du site).
Ou un autre nom mais il faut alors modifier la variable $rep.
Bonsoir,
Je voudrais également m'associer aux autres pour la qualité de ce script.
J'ai cependant deux questions :
1. Comment n'accepter que certaines extensions de fichiers et pas d'autres [...]
Je voudrais donc n'accepter que des images et non des fichiers .exe ou . php
Comment faire ?
2. Où faut-il rajouter le formulaire anti-spam au formulaire sans javascript ??
Merci et bonne continuation.
Dominique
Réponse du webmestre :
Pour ne charger que des images, ajouter ce test :
<?php
$mimetype = mime_content_type($destination);
# lecture et conversion du fichier
if(!eregi('image',$mimetype)) {
$erreur = "Seulement un fichier de type image SVP";
$focus = 7;
} elseif($openf = @fopen($destination, "rb")) {
$fichier = fread($openf, filesize($destination));
@fclose($openf);
# encodage norme RFC 2045
$piecejointe = chunk_split(base64_encode($fichier));
} else {
$erreur = "Problème de lecture du fichier $name";
$focus = 7;
}
?>
Ceci étant dit, la fonction mime_content_type est dépréciée au profit de FileInfo :
http://fr3.php.net/manual/fr/ref.fileinfo.php
Ce qui ne remet pas en cause ce qui est écrit.
2. Pour ajouter le captcha, modifier :
if (!empty($_POST))
par :
if(!empty($_POST) && !strlen($erreur))
et ajouter tout ce qui est avant cette ligne (le code PHP dans le formulaire anti spam).
A l'intérieur du formulaire HTML, placer n'importe où (de préférence avant la validation):
<html>
<? if($imagecode) { ?>
<? echo "$imagecoden"?><input type="text" name="vateuf" size="<?= $nbrchars?>" maxlength="<?= $nbrchars?>" value="<?= htmlentities($_POST['vateuf'],ENT_QUOTES)?>">
Recopiez les caractères à gauche SVP <a href="<?= $_SERVER['PHP_SELF']."?newcode=1"?>">Nouveau</a>
<? } ?>
</html>
Bonsoir
merci pour ce script très pratique !
je désir enlever la case téléphon et ne laisser que le nom (ou pseudo) + l'adresse mail, j'ai simplement effacé la case Tel mais le script a buggué... rien ne s'affiche sur le navigateur (page blanche)
pouvez vous m'aider svp ?
Merci à vous
Magnifique script !!! Et très réactif...
Bonjour,
juste une petite question : peut-on récuperer les données du formulaire et les afficher dans la page de redirection ? Merci.
Réponse : vous pouvez choisir d'afficher le message dans le formulaire (sans redirection) en prenant soin d'utiliser strip_tags et htmlentities pour éviter l'injection de code. Pour convertir les sauts de ligne : nl2br.
Désolé, j'ai trouvé mon erreur... Une bétise de "/"
Désolé et encore merci pour ce script !!!
ps : Ce script d'article commentable me plait... C'est qui, C'est ou? C'est vous ?...
Réponse du webmestre :
Ce script est entièrement développé par mes soins. Merci.
Bonjour Pierre, Bonjour tout le monde...
Alors avant de commencer, je vais vous signaler que je débute dans le "Webmastering" en général... Autrement dit je ne vois pas spécialement de différence entre tous les languages..
Mais bon j'ai quand même reussi a faire quelque chose de pas mal que je mettrais en ligne surement prochainement...
VOICI MA QUESTION :
"Pourquoi crée t-on un dossier 'upload' si les pieces jointes sont envoyées sur ma boite mail ?"
En fait je voudrais que les fichiers atterissent directement sur MON serveur afin de ne pas a les "re-uploader" si je veux les mettre en ligne tot ou tard , mais que j'ai juste a les déplacer dans un autre dossier...
Peut etre que je dis une bétise, je m'en excuse auparavant.... mais j'ai vraiment du mal a tout comprendre dans le code (je parle des codes en général, celui ci a l'avantage de convenir a tout le monde, et c'est parfaitement ce que je cherchais, ca m'évite de faire valider 2 formulaires differents a mes visiteurs...
En attendant une réponse de quelqu'un, Je vous remercie tous et Monsieur Pierre en particulier. Je trouve ca bien de faire partager le fruit de son labeur... Bravo.
A bientot !!
Denis a.k.a Capo
Merci pour cette application de formulaire avec pièce jointe que j'essaie d'utiliser.
Je butte néanmoins sur un point...
Si je fais une erreur (exprès pour un test) dans la saisie, un message m'alerte et me dit quel champ n'est pas bon. Par contre, l'adresse du fichier joint disparait ??
Avez-vous une solution pour ce problème ?
Merci
Michel
Réponse du webmestre :
Malheureusement non, pas à ma connaissance. Il faut détecter que l'upload de fichier a été demandé et, en car d'erreur, avertir l'utilisateur de le recharger.
Sinon, faire l'upload en deuxième phase (une fois que le formulaire est validé). Ce que font certains sites.
Bonjour et merci pour le script.
Cependant il est utile de signaler aux lecteurs que :
$rep est égal à "/" tout court et non pas à "upload/"
Ceci m'a couté deux jours de recherche ... mais en même temps m'a permi d'approfondir mes connaissances en PHP
bonne suite
Réponse du webmestre :
Non Denis : $rep vaut le nom du répertoire que vous aurez choisi pour l'upload.
Si $rep = "upload/" le répertoire "upload" est à créer en FTP (ce n'est peut être pas implicite pour le béotien).
Si $rep = "/" les fichiers seront placées à la racine du site. Pourquoi pas...
bonjour,
il marche trés bien et t'il possible de faire plusieurs envoient de pièces jointes avec ce script?
si oui comment doit-on procéder?
merci d'avance.
Bonjour Pierre,
Félicitation pour votre code ... magnifique et extrêmement facile d'utilisation.
Par contre je me pose des questions au niveau de la sécurité de votre code.
Est il mis à jour régulièrement ? Et la protection est elle suffisante contre les injections SQL et autre joyeuseté de ce genre.
Merci d'avance.
Réponse du webmestre :
Pour le spam voir le formulaire anti-spam, ici même. Pour ce qui concerne l'injection de données SQL, ce scipt n'utilise pas de bdd...
Merci. Implémenté pour l'envoi de communication sur le site d'un congrès scientifique. J'ai bien sur laissé les sources. ;)
Bonjour,
J'ai inserer le formulaire dans ma page tout fonctionne au poil, mais je n'ai pas le script "téléchargement de fichier"
QUE PUIS JE FAIRE ?
Réponse du webmestre :
Tu as dû oublier de créer et/ou définir le répertoire $rep. Si ce dernier n'est pas conforme, l'option upload n'est pas activée.
Une petite rectification pour mime_content_type :
<?
function GetExtensionName($File)
{
return strtolower(substr($File, strrpos($File, '.')));
}
function mime_content_type($fichier)
{
# ajouter autant de combinaisons que souhaitées
$mime = array(
'.gif' => 'image/gif',
'.jpg' => 'image/jpeg',
'.psd' => 'image/x-xwd',
'.png' => 'image/png',
'.txt' => 'text/plain',
'.doc' => 'application/msword',
'.xls' => 'application/vnd.ms-excel',
);
if (!isset($mime[GetExtensionName($fichier)]))
{
return "application/octet-stream";
}
else
{
return $mime[GetExtensionName($fichier)];
}
}
?>
Bonsoir tous
Merci Pierre pour ta réponse!
Si je recharchais la sécurité, le titre de formulaire sans javascript a de suite retenu mon attention, désireux de garder l'xtml+css+un peu de php.
Le soucis des validateurs, notamment celui du WAI pour les handicaps.
Reprenons dans l'ordre:
1/ oui mais comme dit avant, le lien vers le formulaire sera dans plusieurs pages.Et meme il y aura deux formulaires, l'un avec plus de champs textes.
Se sera un site de tutos et donc, de temps en temps, au milieu du texte, je vais faire un lien pour les questions.
D'ou mon soucis de revenir sur le point exact.
Si je prend le tutoriel sur l'Embedded, 6pages, 80 photos, il serait fastidieux de revenir a la page index et refaire la recherche.
Bien sur, comme le php n'est pas mon copain, si la possibilité existe, je suis partant de suite.
2/J'ai suivi les conseils, bien sur, et appliqué les changements.
Le resultat plus loin.
3/J'avais testé avant la réponse pour le Doctype et pas de probleme.
J'ai aussi appliqué le rajout de code.
Mais le xhtml+css sont mes copains.
Avoir un beau script bien sécurisé et sans JS est une chose.
Garder le style de son site aussi.
J'ai respecté le code, joué sur le style seulement et tout marche bien pour l'instant.
Je m'y suis mis, et soyons honnete, c'est 5h qu'il m'a fallu, toujours ce probleme de copinage avec php, mais on avance bien dans nos relations. :D
Voila, je vous livre le résultat et poserais quelques questions, car je suis un peu bloqué pour l'instant.
http://griggione.free.fr/web/pics1/site9.png
1/ comment faire pour redimensionner le champ de Objet
2/ comment faire pour donner un lien vers le fichier css pour styliser le message de reponse bien envoyé, etc.....
3/ .....déja vu pour revenir à la page voulue.
Voila, et une fois fini ces modifs, je m'attaque aux parties upload et protection anti-spam.
Non Pierre, pas sur la tete.
Bonjour
Un nouveau fan pour ce script :D
Pourquoi,ben parce en recherche d'un script sécurisé, Google m'a donné ce lien.
Et pour de bon c'est notre ami. ;)
Quelques questions du nembie de service:
1/ j'ai esayé de mettre onClick='history.go()' pour revenir à la page en cours (le lien formulaire sera sur plusieurs pages),ça passe pas.
2/ Si je comprend bien,pour retirer ou mettre une obligation de remplir un champ,il faut enlever dans: # vérification des champs requis (Nom, Objet, Message, Email ou Tel)
Et je suppose rectifier le numero de: $focus = 5;
3/Peut-on changer le Doctype sans probleme,puisque je suis en (x)HTML 1.0....normalement oui.
En tout cas merci pour ce script qui va surement prendre sa place dans le site.
Et l'url dans la page lien ;)
Réponse du webmestre :
1. je ne vois pas trop l'intérêt d'utiliser du javascript.
2. dans le code PHP ajouter/supprimer :
if (empty($_POST['nom_du_champ'])) {
$erreur = "Merci de renseigner nom_du_champ";
$focus = id_erreur;
}
Dans la balise HTML du champ concerné ajouter/supprimer :
<input name="nom_du_champ"<? if($focus == id_erreur) echo " class="focus"";?>>
3. vérifier les balises non fermantes (ex. <br />), ajouter </option> dans le menu déroulant, vérifier le code avec Tidy.
Bon , c'est tapis rouge respect et dans le plus pur esprit open source.Voila des contributions simples fonctionnelles utilisables même par un débutant comme moi....je ne saurais qu'encourager de telles initiatives rarement de ce niveau!!!!
Bravo et merci
Hervé
Un grand merci!
Je débute en php (je suis webdesigner, mais je n'aime pas trop mettre le nez dans le code) et j'aimerais savoir si ce code est facilement modifiable pour permettre l'upload de 2 fichiers.
Merci d'avance
Très bon script, même pour un amateur ;)
cependant, j'ai un message d'erreur pour tous les objets de mon formulaire :
Notice: Undefined index: Message in contact.php on line 259
J'utilise le formulaire original, mis à jour avec mon adresse mail et ma page de redirection, ces tests s'effectuent en local avec easyphp. Les mails partent bien, je les reçois et si les 2 champs obligatoires ne sont pas remplis, j'ai bien les champs "jaunes".
Même en tentant d'initialiser des valeurs avec l'appel de la page contact.php?Nom=&.... :/
Merci pour ce superbe code et toutes les explications très claires qui vont avec.
Dommage que la mise en oeuvre soit compliquée. Ce serait peut être mieux de mettre tous les fichiers nécessaires dans le zip et un ReadMe. Script trés intéressant mais mise en application à revoir.
bonjour,
tres tres bien votre formulaire le meilleur jamais vu, mais un pour un debutant en php , tres difficile de rajouter des cases a cocher et des selects sans exemples surtout si on veut que certains ne soient pas obligatoires. j'ai essayer de faire un select mais ils m'envoie les numeros du tableau pas les variables.
ce serait vraiment cool un exemple avec tous ce qu'on peux imaginer de mettre dedans.
amicalement
bounounours qui pousse un peu il est vrai :O)
Réponse du webmestre :
<?php
/******* Ajout d'un menu déroulant *******/
# au début du script, déclaration du tableau
# option menu déroulant 'Choix'
# ajout d'option : 'n'=>'Choix 1', 'n+1'=>'Choix 2',
# la première ligne (optionnelle) impose un choix
$selecteur = array(
0 => 'Choisissez',
1 => 'Choix 1',
2 => 'Choix 2',
3 => 'Choix 3',
);
/* après if ($_POST) seulement si $selecteur[0] = 0 */
if (!$_POST['Choix']) {
$erreur = "Merci de renseigner Choix";
$focus = 20; # valeur différente des autres $focus
}
?>
<!-- dans le formulaire -->
<p><label for="Choix">Choix</label>
<select name='Choix' <? if($focus == 20) echo "class="focus"";?> id="Choix">
<?
foreach($selecteur as $key => $val) {
echo " <option value='$key'";
if($key == $_POST['Choix']) echo " selected";
echo ">$valn";
}
?>
</select></p>
bonjour
en effet, c'est du tres beau travail
avez vous une solution afin que l'email soit confirmé?
c'est a dire avoir un deuxième champ email qui vérifie que sa valeur soit bien égale a celle du premier?
merci d'avance
zeitoun
bonjour,
super boulot, vraiment bravo! fontionne nickel!
g un pb, et pas seulement avec votre formulaire (cela fait 3 jours que j'essaie): quand je joints un fichier de plus de 300ko, j'ai un échec d'envoie du mail; comme si il y avait un timeout (soit dans le traitement, soit dans l'upload chez mon hébergeur). L'upload se passe bien car je peux sauver mon fichier (jusqu'à 2Mo) et le retrouver chez mon hebergeur. peut-être que vous pourrez me donner une solution... vue vos connaissances en envoie de mail.
Merci. Vincent
(NDLA : problème ponctuel résolu)
bonjour,
comment on fait pour ajouter des cases à cocher ?
tres bien ce formulaire!
merci
Réponse du webmestre :
<?php
if ($_POST) {
if (!$_POST['jailu']) {
$erreur = "Merci de cliquer la case à cocher";
}
}
?>
<? if (!$_POST || $erreur) { ?>
<input type="checkbox" name="jailu" value="1" <? if($_POST['jailu']) echo "checked"?>> J'ai lu et approuvé
<? } ?>
http://dev.ppan.net [Document mis à jour le 07.01.2011]