[PHP] empêcher de valider 2fois un formulaire [Résolu/Fermé]

Signaler
Messages postés
11760
Date d'inscription
mardi 1 février 2005
Statut
Modérateur
Dernière intervention
8 août 2019
-
 joan -
Bonjour,

J'ai un formulaire HTML qu'un utilisateur doit remplir. Cliquer sur "Valider" appelle un script PHP qui, entre autres, envoie un mail. Chaque soumission de données par l'intermédiaire du formulaire est identifiée et rendue unique aux yeux du serveur par une signature md5 (du coup le formulaire remplit par DUPONT Joseph, 2 rue des Platanes, 75000 PARIS et celui de DUPONT Joseph Lieu dit les embruns 69000 LYON auront une signature différente). Le problème est que, durant le temps où l'utilisateur clique une première fois sur "envoyer" et jusqu'au moment où le script PHP termine son exécution et informe l'utilisateur que sa demande a été envoyée, celui-ci a le temps de cliquer encore plusieurs fois sur "Valider". De ce fait, le script est exécuté à nouveau, autant de fois que l'utilisateur a cliqué. De ce fait, certaines fois 5 mails sont envoyés pour un utilisateur unique.

Je cherche donc à y remédier, sachant que je n'utilise aucune base de données (et je voudrais en n'utiliser aucune), et que le seul moyen d'identifier des "doublons" c'est de différencier le hash. Je pensais qu'il serait possible de créer un fichier par exemple antidoublons.txt (dans lequel seraient enregistrés les hashs en cours). Au début du script je vérifie qu'aucun hash identique à celui que je vais traiter n'est trouvé dans ce fichier, si c'est le cas je poursuis l'exécution du script, sinon je ne fais rien. A la fin du script, je supprime le hash correspondant à le demande traitée.

Mais cela impose :
* l'ouverture/Ecriture d'un fichier
* l'utilisation de la recherche avec des expressions régulières deux fois (une première pour vérifier que la signature n'existe pas, une seconde pour la supprimer)

Et au final ça risque d'allonger énormément la durée d'exécution du script. Et puis je suis pas sûr que ça fonctionne merveilleusement bien, surtout dans le cas où plusieurs demandes seraient effectuées "en même temps".

Y aurait-il une solution plus simple ? Je suis eprduadé que oui :)
Merci !

10 réponses

Messages postés
11760
Date d'inscription
mardi 1 février 2005
Statut
Modérateur
Dernière intervention
8 août 2019
2 257
J'ai fini par choisir la solution de facilité : Avec Javascript : http://www.journaldunet.com/developpeur/tutoriel/dht/031202_javascript.shtml
Tant pis pour les 3% d'utilisateurs qui n'activent pas JS.....
5
Merci

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

CCM 65492 internautes nous ont dit merci ce mois-ci

Messages postés
4606
Date d'inscription
lundi 7 novembre 2005
Statut
Contributeur
Dernière intervention
24 octobre 2020
1 292
Salut,

que penserais tu d'utiliser les sessions php. tu y stockes une variable soumission. Par défaut, soumisison n'existe pas.
et ca donnerait qqch du genre :

tu valides
si $_SESSIONS['soumission']  existe_pas
    alors : envoi du mail ; autre actions; $_SESSIONS['soumission'] = "soumis" ;
sinon
    ($_SESSIONS['soumission']  existe (= soumis)...)
    alors je sors de la boucle car le formulaire a deja été soumis
Messages postés
11760
Date d'inscription
mardi 1 février 2005
Statut
Modérateur
Dernière intervention
8 août 2019
2 257
Salut,
A voui, je vais aller voir de ce côté-là, je ne connais pas. Merci.
Messages postés
11760
Date d'inscription
mardi 1 février 2005
Statut
Modérateur
Dernière intervention
8 août 2019
2 257
Re,
J'ai essayé :

//Création signature MD5
$signnc=$nom.$prenom.$adresse;
$sign=md5($signnc);

// Session
session_start();
if($_SESSION['md5']==$sign)
     {
     }
else
     {
     $_SESSION['md5']=$sign;
     mail(....);
     ....
     ....
     }


Et ça a l'air de marcher : http://cjoint.com/data/lboQO2HGLH_sess.png

Néanmoins :
1- si la signature (md5) est identique à $sign, je voudrais qu'il ne se passe rien .... à part terminer l'exécution du script lancé lors du premier clic sur "valider". Or ici (et même problème avec break ou exit), si je clique plusieurs fois sur "valider", je me retrouve avec une page blanche, chose qui n'arrive pas si je ne clique qu'une fois. Est-ce que le 'nouveau' script lancé par le second clic sur "valider" a "annulé" l'exécution du premier script ? A mon sens oui, puisqu'ils ont le même nom de fichier. Comment pourrais_je éviter cela ?

2- Je voudrais comprendre un peu plus les choses :
Qu'est-ce que c'est, au final, que la session ? Est-ce que, (graphiquement, voir lien ci-dessus) elle correspond au dossier ayant pour nom le domaine ? Dans ce cas-là une session n'expire jamais alors ? Ce sont les variables stockées à l'intérieur qui expirent ?
Comment se fait-il que la variable (que j'ai appelé ici md5) ne soit nommée nulle part ? Correspond-elle au fichier PHPSESSID ? N'est-ce pas plutôt la session ? Enfin, je m'embrouille :-/
Merci :-))
Messages postés
4606
Date d'inscription
lundi 7 novembre 2005
Statut
Contributeur
Dernière intervention
24 octobre 2020
1 292
hello,

Pour le 1) je n'ai pas de solution à te proposer. Une question cependant : est ce que le traitement du formulaire est géré par la page formulaire elle même ? Si oui, essayes (a tout hasard) de voir si en gérant l'execution par une autre page (form.html &rarr method post ou get, action="exectionForm.php")
Je suppose, peut être à tord, que dès lors que le formulaire sera soumis, la page form ne sera plus accessible par l'utilisateur, donc plus de risque de cliquer une seconde fois.

Pour le 2) une session est créée par le script. c'est en qq sorte un fichier temporaire contenant des informations que tu lui a fournit, et géré par le serveur. celle ci est conservée tant que l'utilisateur ne fermes pas son navigateur (si mes souvenirs sont bons). Elle expire donc lors de la fermeture ( avérifier). La session, que tu retrouves chez free dans le dossier /sessions (que tu dois créer toi même a la racine), est stockée dans le fichier portant le nom bizaroide d5cd.... si tu ouvres ce fichier (une session utilisateur),tu constateras qu'à l'intérieur les variables de session y sont stockées
donc le fichier PHPSESSID (la session utilisateur) est le fameux fichier d5cd... et si tu l'ouvres, tu devrais y voir inscrit : md5:le_hash qui correspond à la variable que tu y a stocké

suis je clair ? hmmm pas sur ...
Messages postés
11760
Date d'inscription
mardi 1 février 2005
Statut
Modérateur
Dernière intervention
8 août 2019
2 257
Non, le fichier gérant l'entrée de données dans le formulaire est déjà différent du fichier contenant le formulaire.

Ah, en fait les variables sont stockées sur le serveur, pas dans le cookie ? Le cookie renvoie seulement aux données contenues sur le serveur, mais il ne contient rien du tout ?
Si je demande à enregistrer 2 variables, alors il va se créer un second cookie côté client et un second fichier côté serveur ? Chaque "fichier côté serveur" n'enregistre que la valeur d'une seule et unique variable ?

Mais alors dans mon cas, puisque je ne demande jamais explicitement de détruire les variables, dans un mois je me retrouve avec 100.000 fichiers correspondant aux 100.000 dernières variables enregistrées pour tous les utilisateurs ? Même si ça n'atteindra certainement pas 100.000 pour moi ça risque qu'en même d'être embêtant, non ? :)
Messages postés
11760
Date d'inscription
mardi 1 février 2005
Statut
Modérateur
Dernière intervention
8 août 2019
2 257
Le click "valable" générera une page de confirmation, après ton traitement, et pas forcément via un header
Mais le script "valable" est 'interrompu' par les autres clics avant qu'il ne redirige vers la page de confirmation. .... ou alors j'ai rien compris, puisqu'actuellement le script fonctionne déjà comme ceci, mais avec des sessions PHP. Et pourtant je me retrouve avec une page blanche si je valide plusieurs fois.

Mais au final, si ça peut résoudre le problème juste en utilisant des cookies, ça me convient puisque je n'ai pas spécialement d'intérêt de stocker ces infos sur le serveur.
Salut,

Une piste, poser un cookie par le fichier qui traite le formulaire, et verification avant de faire un traitement que le cookie n'existe pas déja.

dans ton fichier .php traitement:

1- tu viens lire le cookie (nommé trace par exemple)

2- si cookie trouvé (et correspondant au md5), tu sort du script sans rien faire

- si cookie pas trouvé, tu ecrit le cookie 'trace' avec comme valeur ton md5
et tu fait ton traitement

A noter aussi que tu peux poser et lire des cookie par Javascript

dans ta balise <form ......................... onSubmit="return verif_1_click();">

fonction JS verif_1_click{
tu viens lire le cookie

si present et ok tu fais return=false

sinon

tu ecris le cookie et tu fais return=true
le formulaire ne sera envoyé que dans ce cas là
}

Pour coder tout ça vas voir comment faire sur Google, je t'ai donné seulment le principe
Messages postés
4606
Date d'inscription
lundi 7 novembre 2005
Statut
Contributeur
Dernière intervention
24 octobre 2020
1 292
Salut,
Ca n'amenera rien de plus... ce que tu lui propose, consiste simplement à remplacer la session par un cookie ...
Messages postés
11760
Date d'inscription
mardi 1 février 2005
Statut
Modérateur
Dernière intervention
8 août 2019
2 257
Euh, il me semble que c'est déjà ce qui se passe :)
Le problème c'est lorsque "je sors du script sans rien faire" (ton 2-) je me retrouve avec une page blanche, alors qu'un traitement "normal" (pour lequel on aurait cliqué une seule fois sur "valider"), j'aurais dû être redirigé grâce headers(); vers une autre page de confirmation.

> Ah, parce qu'en plus "cookie" n'implicite pas forcément "session" ? Je vais potasser un peu de docs alors >:-)
Messages postés
4606
Date d'inscription
lundi 7 novembre 2005
Statut
Contributeur
Dernière intervention
24 octobre 2020
1 292 >
Messages postés
11760
Date d'inscription
mardi 1 février 2005
Statut
Modérateur
Dernière intervention
8 août 2019

cookie = enregistré sur le disque dur de l'utilisateur
session = enregistré sur le serveur
Bonjour,

Le problème c'est lorsque "je sors du script sans rien faire" (ton 2-) je me retrouve avec une page blanche

Ce n'est pas parce que tu sort d'un test dans un script sans rien faire que tu génères une page blanche.

Le click "valable" générera une page de confirmation, après ton traitement, et pas forcément via un header
Coucou ! :-)

Solution imaginée à l'instant.. :-)

Bon, un fichier texte généré dans un répertoire sur le serveur :
ip/213.213.213.213.txt

Fichier existant pour l'envoi.
Après validation, vérifier si le fichier existe et ensuite à la fin du traitement, supprimer le fichier nommé 213.213.213.213.txt

Si l'internaute réactualise, le fichier est vérifié si il est existant.. pas de bol pour lui, il est supprimé donc le formulaire ne sera pas une seconde fois envoyé..

Intéressant ?
Bon amusement ;)
Mikado
le post est un peu vieux mais intéressant donc voici une réponse possible (sans utiliser js ) :
lors de l'envoie du formulaire,
verification
$_SESSION['sended']!= true;
une foi le traitement fini
$_SESSION['sended']= true;
voila