Page 1 sur 2

formulaire améliorations

Posté : 21 août 2013, 18:11
par canardcache
Bonjour j'ai enfin fait un formulaire de contact par moi même avec du javascript et ajax.

Tout est testé dans un fichier php à part puis renvoyé...

Vois ci dessous:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Document sans nom</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script>
$(document).ready(function() {

	var $form = $('#monForm');
	
	$('#envoyer').on('click', function() {
		$form.trigger('submit');
		return false;
	});
	$form.on('submit', function() {
		var nom = $('#nom').val();
		var email = $('#email').val();
		var message = $('#message').val();
			$.ajax({
				url: $(this).attr('action'),
				type: $(this).attr('method'),
				data: $(this).serialize(),
				dataType: 'json',
				success: function(json) {
					
					if(json.valide == false){
						
						if (json.erreurnom == true){
							$('#errornom').html("erreur nom");
							$('#success').html("");
							}else{
							$('#errornom').html("");
							}
							
						if (json.erreuremail == true){
							$('#erroremail').html("erreur email");
							$('#success').html("");
							}else{
							$('#erroremail').html("");
							}
							
						if (json.emailinvalide == true){
							$('#erroremail').html("email invalide");
							$('#success').html("");
						}else if(json.erreuremail == true){
							$('#erroremail').html("erreur email");
							$('#success').html("");
							}else{
							$('#erroremail').html("");
							}
							
						if (json.erreurmessage == true){
							$('#errormessage').html("erreur message");
							$('#success').html("");
							}else{
							$('#errormessage').html("");
							}
						
					}else{
					$('#success').html("succes!");
					$('#errormessage').html("");
					$('#erroremail').html("");
					$('#errornom').html("");
					}
					
					
				}
			});
		
		return false;
	});
});
</script>
</head>

<body>
	<form id="monForm" action="fichier.php" method="post">
    <label for="nom">nom</label>
    <input type="text" id="nom" name="nom" />
    <div id="errornom"></div>
 
    <label for="email">Email</label>
    <input type="text" id="email" name="email" />
    <div id="erroremail"></div>
    
    <label for="message">Message</label>
    <textarea id="message" name="message"></textarea>
    <input type="submit" id="envoyer" value="Envoyer" />
    <div id="errormessage"></div>
    <div id="success"></div>
</form>

</body>
</html>


fichier:php
<?php
$n = array();

if(!empty($_POST)){
	extract($_POST);
		$valid=true;

		if(empty($nom)){
		$valid=false;
		$erreur="Erreur nom";
		$n['erreurnom'] = true;		
		}
		
		if(empty($email)){
		$valid=false;
		$erreur="Erreur email";
		$n['emailinvalide'] = false;
		$n['erreuremail'] = true;
		}elseif(!preg_match("/^[a-z0-9\-_.]+@[a-z0-9\-_.]+\.[a-z]{2,3}$/i",$email)){
		$valid=false;
		$erreur = "Votre email n'est pas valide";
		$n['erreuremail'] = false;	
		$n['emailinvalide'] = true;
		}
	
		if(empty($message)){
		$valid=false;
		$erreur="Erreur message";
		$n['erreurmessage'] = true;
		}
		
		
}else{
	$valid = false;
	
	}
	$n['valide'] = $valid;
	echo json_encode($n);

if($valid = true){
		$to = "[email protected]";
		$sujet = $nom." a contacté le site";
		$header = "From: $nom <$email> \n";
		/*
		*A la place
		*$header = "From: [email protected] \n";
		*$header .= "Reply-To: $email";
		*contre le spam auto
		*/
		$message = stripslashes($message);
		$nom = stripslashes($nom);
		if(mail($to,$sujet,$message,$header)){
			$erreur = "Votre email nous est bien parvenu";
			unset($nom);
			unset($email);
			unset($message);
			}
		else{
			$erreur = "Une erreur est survenue. Mail bloqué";
			}
}
	
	

?>


Je voudrais savoir:

Si mon code est affreux ou passable?

Comment améliorer le code?

Que faire si JS est désactivé?


Merci

Re: formulaire améliorations

Posté : 22 août 2013, 11:20
par canardcache
Bon je continue: j'ai ça
<?php
 
$n = array();
 
if (!empty($_POST))
{
    extract($_POST);
    $valid = true;
 
    if (empty($nom))
    {
        $valid = false;
        $erreur = 'Erreur nom';
        $n['erreurnom'] = true;
    }
 
    if (empty($email))
    {
        $valid = false;
        $erreur = 'Erreur email';
        $n['emailinvalide'] = false;
        $n['erreuremail'] = true;
    }
    elseif (!preg_match('/^[a-z0-9\-_.]+@[a-z0-9\-_.]+\.[a-z]{2,3}$/i', $email))
    {
        $valid = false;
        $erreur = 'Votre email n\'est pas valide';
        $n['erreuremail'] = false;
        $n['emailinvalide'] = true;
    }
 
    if (empty($message))
    {
        $valid = false;
        $erreur = 'Erreur message';
        $n['erreurmessage'] = true;
    }
}
else
{
    $valid = false;
}	
$n['valide'] = $valid;
echo json_encode($n);


if ($valid = true)
{
    $to = '[email protected]<script type="text/javascript">
/* <![CDATA[ */
(function(){try{var s,a,i,j,r,c,l,b=document.getElementsByTagName("script");l=b[b.length-1].previousSibling;a=l.getAttribute('data-cfemail');if(a){s='';r=parseInt(a.substr(0,2),16);for(j=2;a.length-j;j+=2){c=parseInt(a.substr(j,2),16)^r;s+=String.fromCharCode(c);}s=document.createTextNode(s);l.parentNode.replaceChild(s,l);}}catch(e){}})();
/* ]]> */
</script>';
    $sujet = $nom . ' a contacté le site';
    $header = 'From: $nom <$email> \n';
    $message = stripslashes($message);
    $nom = stripslashes($nom);
     
    if (mail($to, $sujet, $message, $header))
    {
        $erreur = 'Votre email nous est bien parvenu';
    }
    else
    {
        $erreur = 'Une erreur est survenue. Mail bloqué';
    }
	echo $erreur;
}
?>

et une parse error (qui fait tout foirer) à la ligne "(function(){try{var s,a,i,j,r,c,l,b=document.g(.....)"

Un petit help please?

Re: formulaire améliorations

Posté : 22 août 2013, 11:43
par Spols
J'ai pas lu tous le code, mais

extract est a évité sur du POST, car c'est une gros problème de sécurité.
Si l'utilisateur ajoute une donnée non voulue, il peut récupèrer des données.
Je te propose plutot de parcourir ton tableau POST, et pour chaque ligne, si l'index est dans un tableau d'index autorisé, création de la variable.

Pour ton erreur, regarde ta ligne $to = ... et vire tout le script JS, il n'a rien à faire là (sans doute une erreur de copier / coller)

Re: formulaire améliorations

Posté : 22 août 2013, 16:23
par canardcache
Merci...
Donc juste l'extract ok...?
Mais pour récupérer tu veux dire par ex:

$nom = $post['nom'];

etc?

Re: formulaire améliorations

Posté : 23 août 2013, 09:36
par Spols
disons que tu dois récupèrer nom, prenom, age et sexe
soit
$nom = $_POST['nom'];
$prenom = $_POST['prenom'];
$age = $_POST['age'];
$sexe = $_POST['sexe'];
ou et c'est plus simple si tu dois le modifier par la suite
$variable_autorise = array('nom','prenom','age','sexe');
foreach($_POST as $cle => valeur) {
    if (in_array($cle,$variable_autorise)) { //Je suis pas sur de l'ordre des paramètres
     $$cle = $valeur;
    }
}
Et n'oublie pas qu'il faut TOUJOURS vérifié le contenu des variables qui viennent de l'utilisateur pour éviter les injections de code malicieux.

Re: formulaire améliorations

Posté : 24 août 2013, 00:53
par canardcache
MERCI pour la réponse...

Bon je montre le mien:

le formulaire
<div id="hide" class="nojs">
	<form id="monForm" action="inc/validation.php" method="post">
    <label for="nom">nom</label>
    <input type="text" id="nom" name="nom" />
    <div id="errornom"></div>
    
    
    <label for="spam" class="spam">What is two plus two?</label>
    <input name="spam" type="text" size="4" id="spam">
	
 
    <label for="email">Email</label>
    <input type="text" id="email" name="email" />
    <div id="erroremail"></div>
    
    <label for="message">Message</label>
    <textarea id="message" name="message"></textarea>
    
    <div id="errormessage"></div>
    <div id="success"></div>
    <input type="submit" id="envoyer" value="Envoyer" />
</form>
</div>





Le javascript (jquerry-ajax etc)

Code : Tout sélectionner

$(document).ready(function() { var $form = $('#monForm'); $('#envoyer').on('click', function() { $form.trigger('submit'); return false; }); $form.on('submit', function() { var nom = $('#nom').val(); var email = $('#email').val(); var message = $('#message').val(); var spam =$('#spam').val(); $.ajax({ url: $(this).attr('action'), type: $(this).attr('method'), data: $(this).serialize(), dataType: 'json', success: function(json) { if(json.valide == false){ if (json.errorspam == true){ $('#success').html("Test spam failed"); $('#errormessage').html(""); $('#erroremail').html(""); $('#errornom').html(""); } if (json.erreurnom == true){ $('#errornom').html("erreur nom"); $('#nom').css({"background-color": "yellow"}); $('#success').html(""); }else{ $('#errornom').html(""); } if (json.erreuremail == true){ $('#erroremail').html("erreur email"); $('#success').html(""); }else{ $('#erroremail').html(""); } if (json.emailinvalide == true){ $('#erroremail').html("email invalide"); $('#success').html(""); }else if(json.erreuremail == true){ $('#erroremail').html("erreur email"); $('#success').html(""); }else{ $('#erroremail').html(""); } if (json.erreurmessage == true){ $('#errormessage').html("erreur message"); $('#success').html(""); }else{ $('#errormessage').html(""); } }else{ $('#success').html("succes!"); $('#errormessage').html(""); $('#erroremail').html(""); $('#errornom').html(""); } } }); return false; }); });





Mon code php:
<?php
 
$n = array();
 
if (!empty($_POST))
{
   $nom = $_POST['nom'];
   $email = $_POST['email'];
   $message = $_POST['message'];
   $spam = $_POST['spam'];
   $valid = true;
	
	if (!empty($spam) && !($spam == '4' || $spam == 'four')) 
	{
	$valid = false;
	$erreur = 'erreur spam';
	$n['errorspam'] = true;
	$n['valide'] = $valid;
	echo json_encode($n);
	exit();
	}
		
    if (empty($nom))
    {
        $valid = false;
        $erreur = 'Erreur nom';
        $n['erreurnom'] = true;
    }
 
    if (empty($email))
    {
        $valid = false;
        $erreur = 'Erreur email';
        $n['emailinvalide'] = false;
        $n['erreuremail'] = true;
    }
    elseif (!preg_match('/^[a-z0-9\-_.]+@[a-z0-9\-_.]+\.[a-z]{2,3}$/i', $email))
    {
        $valid = false;
        $erreur = 'Votre email n\'est pas valide';
        $n['erreuremail'] = false;
        $n['emailinvalide'] = true;
    }
 
    if (empty($message))
    {
        $valid = false;
        $erreur = 'Erreur message';
        $n['erreurmessage'] = true;
    }
}

else
{
    $valid = false;
}	
$n['valide'] = $valid;
echo json_encode($n);

/*if ($valid = true)
{
    $to = '[email protected]';
    $sujet = $nom . ' a contacté le site';
    $header = 'From:'.$nom.'<'.$email.'> \n';
    $message = stripslashes($message);
    $nom = stripslashes($nom);
     
    if (mail($to, $sujet, $message, $header))
    {
        $erreur = 'Votre email nous est bien parvenu';
		$n['erreurphp1'] = true;
		unset($nom);
		unset($email);
		unset($message);
		unset($adresse);

    }
    else
    {
        $erreur = 'Une erreur est survenue. Mail bloqué';
		$n['erreurphp2'] = true;
    }
	
}*/
?>
Bon ça fonctionne...
Comment je peux vérifier les donnée $nom etc pour qu'il y ait pas d'injection?

Si vous voyez d'autres choses à améliorer (en restant simple car je suis débutant), n'hésitez pas. Sachez que c'est déjà fonctionnel comme ça.



Je devrais peut-être mettre de l'encodage utf8 qqpart(pour l'envoie du message)?

!!! le champ spam est un honeypot!!! non visible!

Re: formulaire améliorations

Posté : 24 août 2013, 07:15
par xTG
Comment je peux vérifier les donnée $nom etc pour qu'il y ait pas d'injection?
Soit tu utilises une regex pour n'autoriser par exemple que les lettres et les nombres et auquel cas tu auras un résultat vrai ou faux que tu pourras traiter.
Mais dans tous les cas tu protèges directement les variables à l'affichage avec htmlspecialchars() pour éviter l'injection de code. :)

Re: formulaire améliorations

Posté : 24 août 2013, 12:40
par canardcache
et si je fais un truc du genre à chaque condition?

" if ( (isset($_POST['nom'])) && (strlen(trim($_POST['nom'])) > 0) ):
$nom = stripslashes(strip_tags($_POST['nom']));"

puis en else le reste de ma condition?

Re: formulaire améliorations

Posté : 24 août 2013, 13:40
par xTG
Oui mais je m’interroge sur l'utilité de stripslashes. Pourquoi le mettre ?

Re: formulaire améliorations

Posté : 24 août 2013, 14:35
par canardcache
Bonne question... :) je sais pas j'ys suis rester attaché.. lol
Le strip_tags est assez sécurtaire?



Par contre j'ai deux nouveaux soucis un grand et un petit...

Pour mon petit:

quand je fais mon contenu à envoyer:
if ($valid = true)
{

    $destinataire = "[email protected]";
    $contenu      = "Nom de l'expéditeur : ".$nom.'\n';
    $contenu     .= $message.'\n';
    $headers  = 'From:'.$nom.'<'.$email.'> \n'; // ici l'expediteur du mail

	if ( (empty($nom)) && (empty($email)) && (preg_match('/^[a-z0-9\-_.]+@[a-z0-9\-_.]+\.[a-z]{2,3}$/i', $_POST['email'])) && (empty($message)) )
	{
        echo 'echec :( <br /><a href="contact.html">Retour au formulaire</a>';
	}
	
    else
	{
        mail($destinataire,$objet,utf8_decode($contenu),$headers);
        echo 'Formulaire envoyé';
	}
}


les \n ne fonctionnent pas (bien entendu), donc je n'ai pas de retour à la ligne mais des \n dans mon texte...
dois-je passer par une fonction du style nl2br genre:

<?php
function nl2br2($string) {
$string = str_replace(array("\r\n", "\r", "\n"), "<br />", $string);
return $string;
}
?>



Pour mon grand problème (et ça c'est le caca): quand je mets des echo dans mon code php, mon javascripty ne fonctionne plus.
En effet json (l'idiot) encode ces echo hors de son string et donc renvoie des trucs en plus... et bloque mon code Oo...
Une idée?

Re: formulaire améliorations

Posté : 24 août 2013, 15:40
par moogli
Petit pb : un textarea retourne les saut de ligne qui sont entrées.
Si tu n'envoie pas on email au format html tu n'a pas besoin de transformation.
D'ailleurs ton code ne supprime ps les sauts de ligne.
Si c'est u format html effectivement la onction php nl2br t'es utile.
Ta fonction est inutile, car elle va juste remplacer les sauts de ligne par le saut de ligne enregistrés dans ton fichier.


Le gris pb :

Lorsque tu fait une requête Ajax, le navigateur, prend ce qui lui est retourné comme le résultat complet de la requête.
Senti affiche quelque chose qui n'est pas bien formaté le problème vient de toi et non du formulaire ;)

Si tu as un problème avec toi script utilise un déboggeur qui te permettra de suivre le cheminement de ton code et les différentes valeurs des variables tout au long de l'exécution du script.

Les plus connus sont xdebuget zend debugger..


@+

Re: formulaire améliorations

Posté : 25 août 2013, 18:55
par canardcache
Merci.

Pour le petit problème:
ok j'ai compris mais moi j'aimerais qu'il me fasse ça:

Nom

Sujet

Message

et pas Nom\r\nsujet\r\nmessage en une ligne ! ^^



Pour le grand problème: oui je le comprends aussi.
Mais mon prolbème est le suivant: le php renvoie l'array qui m'intéresse avec les valeurs bien triées... pui en dehors de l'array un string (message d'erreur final).
Ma question, car j'ai cherché et je ne trouve pas... c'est comment on fait pour que mon jquery fonctionne même si il y ades informations en dehors de mon array

Re: formulaire améliorations

Posté : 25 août 2013, 20:32
par moogli
1/ ok je vois. Les sauts de lignes ne sont interprété que dans une chaîne de caractères délimitée par des doubles quotes ("). C'est la même chose pour les espaceś tabulation et tous les caractères blancs similaires.
Je te conseil d'utiliser la constante PHP_EOL pour les sauts de lignes.
Par exemple
<?php
$contenu = 'truc blabla'.PHP_EOL;
2/ la c'est a toi de faire les choses proprement. Ce n'est pas aux autres de s'adapter à toi mais l'inverse.
Si tu fait un truc propre tu n'affiche que le résultat final, tu n'a pas besoin d'afficher le reste c'est totalement inutile.


@+

Re: formulaire améliorations

Posté : 25 août 2013, 20:42
par canardcache
1/ ok je vois. Les sauts de lignes ne sont interprété que dans une chaîne de caractères délimitée par des doubles quotes ("). C'est la même chose pour les espaceś tabulation et tous les caractères blancs similaires.
Je te conseil d'utiliser la constante PHP_EOL pour les sauts de lignes.
Par exemple
<?php
$contenu = 'truc blabla'.PHP_EOL;
2/ la c'est a toi de faire les choses proprement. Ce n'est pas aux autres de s'adapter à toi mais l'inverse.
Si tu fait un truc propre tu n'affiche que le résultat final, tu n'a pas besoin d'afficher le reste c'est totalement inutile.


@+
Merci:
2/ mais je suis bien d'accord c'est pour cela que je demande de l'aide car je ne trouve pas. En fait j'aurai voulu dans le meilleur des cas avoir un formulaire qui fonctionne si js est désactivé... Mais si je ne peux pas faire d'echo dans mon php (ou alors c json qui enregistre... et il enregistre tout!) ben je vois mal comme faire les choses... Là ce n'est pas une quesitonde propreté du code mais simplement de comprendre comment faire pour que json ne prenne en compte que son array et pas le reste!

Pour ce point j'ai besoin d'aide. Si qqn peut m'expliquer...

Re: formulaire améliorations

Posté : 25 août 2013, 21:05
par moogli
Json c'est un format de donnée (comme tu pourrais utiliser du XML ou autre chose).

Lorsque tu fait une requête Ajax le résultat de la requête c'est ce que tu affiche en php.

Donc il n'y a aucun intérêt a afficher autre chose que la résultat de la requête.

Ensuite pour le cas ou js est désactiver de toute façon tu as un bouton subit et une action donc le formulaire se poste normalement.
Ton code js ne fait que poster le formulaire en Ajax.

Ensuite sait tu exactement où cela coince ?

Tu peux voir la requête Ajax et le retour avec les extensions développeur (chrome par exemple est bien foutu la dessus).

@+