[RESOLU] formulaire améliorations

Eléphanteau du PHP | 15 Messages

21 août 2013, 18:11

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

Eléphanteau du PHP | 15 Messages

22 août 2013, 11:20

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?

Mammouth du PHP | 1966 Messages

22 août 2013, 11:43

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)
Spols
pour les fan de rubik's cube ou pour les curieux ==> le portail francophone du rubik's cube

Eléphanteau du PHP | 15 Messages

22 août 2013, 16:23

Merci...
Donc juste l'extract ok...?
Mais pour récupérer tu veux dire par ex:

$nom = $post['nom'];

etc?

Mammouth du PHP | 1966 Messages

23 août 2013, 09:36

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.
Spols
pour les fan de rubik's cube ou pour les curieux ==> le portail francophone du rubik's cube

Eléphanteau du PHP | 15 Messages

24 août 2013, 00:53

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!

ViPHP
xTG
ViPHP | 7331 Messages

24 août 2013, 07:15

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

Eléphanteau du PHP | 15 Messages

24 août 2013, 12:40

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?

ViPHP
xTG
ViPHP | 7331 Messages

24 août 2013, 13:40

Oui mais je m’interroge sur l'utilité de stripslashes. Pourquoi le mettre ?

Eléphanteau du PHP | 15 Messages

24 août 2013, 14:35

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?

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

24 août 2013, 15:40

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


@+
Il en faut peu pour être heureux ......

Eléphanteau du PHP | 15 Messages

25 août 2013, 18:55

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

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

25 août 2013, 20:32

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.


@+
Il en faut peu pour être heureux ......

Eléphanteau du PHP | 15 Messages

25 août 2013, 20:42

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

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

25 août 2013, 21:05

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

@+
Il en faut peu pour être heureux ......