Formulaire de contact sans javascript avec pièce jointe

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é).

Fondements

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 !

FAQ

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(!eregi('image',$mimetype)) {
	$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>

Traitement (début de page)

<?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";
# traiter $_GET['mailOK'] dans $pageconfirme (ex. index.php) 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&eacute;l&eacute;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) || eregi("(MAX_FILE_SIZE|Objet)", $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 = ereg_replace("(\n|\r|\r\n)", "<br>", 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
			@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.

[Haut de page]

Affichage (fin de page)

<!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>&nbsp;</label>NB : taille du fichier inférieure à <?= (int)($taillemax/1024)?> Ko
			 </p>
<?		} ?>
			 <p>
				<label>&nbsp;</label><input id="submit" type="submit" value="Envoyer"> <a href="./">Accueil</a>
			 </p>
		  </form>
	</div>
</body>
</html>

Variante (code partiel)

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 :

[Haut de page]

# 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.

supfichier.php

<?php
@unlink($_GET['destination']);
@header("Location: ./");
?>
Thieric a commenté le 29.11.2009

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

Arnaud a commenté le 12.09.2009

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.

Lina a commenté le 04.09.2009

bravo pour ce script très facile à utiliser, très efficace :) !! Merci de le partager !

Lady06 a commenté le 20.07.2009

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

Le_gemaux a commenté le 24.05.2009

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

Pierre a commenté le 24.05.2009

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'];

Carl a commenté le 14.02.2009

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

Pierre a commenté le 14.02.2009

Carl, 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)

Py a commenté le 15.04.2008

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!

Pierre a commenté le 15.04.2008

Py : 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.

Pierre a commenté le 29.10.2007
Dominique, 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>
Dominique a commenté le 29.10.2007

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,

Le_gemaux a commenté le 13.09.2007

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

Roger1664 a commenté le 31.07.2007

Magnifique script !!! Et très réactif...

Didier a commenté le 05.04.2007

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.

Michel a commenté le 30.11.2006

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

Pierre a commenté le 30.11.2006

Michel : 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.

Denis a commenté le 09.11.2006

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

Pierre a commenté le 09.11.2006

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...

Lout a commenté le 12.10.2006

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.

Pierre a commenté le 12.10.2006

Utiliser un formulaire en tableau (une boucle PHP est simple à faire) :
<form>
<input type="file" name="fichier[]">
<input type="file" name="fichier[]">
<input type="file" name="fichier[]">
[...]
</form>
Puis traiter $_POST['fichier'] comme il se doit. Désolé, 'pas le temps de m'y pencher.

Nonel a commenté le 30.09.2006

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.

Pierre a commenté le 30.09.2006

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...

NSH a commenté le 12.09.2006

Merci. Implémenté pour l'envoi de communication sur le site d'un congrès scientifique. J'ai bien sur laissé les sources. ;)

NIMBUS a commenté le 11.09.2006

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 ?

Pierre a commenté le 11.09.2006

Nimbus, 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.

SBégouin a commenté le 11.08.2006

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)];
}
}
?>

Griggione a commenté le 12.05.2006

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.

Griggione a commenté le 11.05.2006

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 ;)

Pierre a commenté le 11.05.2006

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.

Rvb a commenté le 08.05.2006

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é

Bertrand3478 a commenté le 11.04.2006

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

AkhenatonXP a commenté le 02.04.2006

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.

Jari a commenté le 29.03.2006

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.

Bounounours a commenté le 16.03.2006

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)

Pierre a commenté le 16.03.2006
<?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>
Zeitoun a commenté le 28.02.2006

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

Vincz68 a commenté le 20.02.2006

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)

Kevin a commenté le 11.01.2006

bonjour,
comment on fait pour ajouter des cases à cocher ?
tres bien ce formulaire!
merci

Pierre a commenté le 11.01.2006
<?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é
<? } ?>

[Réagir à cet article]

http://dev.ppan.net [Haut de page] [Document mis à jour le 20.07.2009]