Bonjour!
Comment faire en PHP pour éviter les problèmes posés par les variables POST qui font leurs malignes quand on clique sur refresh ou back. Exemple : message posté en double dans les forums, données en double dans la base et tutti quanti...
Merci !!
# Mon astuce
Posté par Twidi (site web personnel) . Évalué à 4.
A la génération du formulaire par mon script, je créé une clé unique (un bon gros rand des familles), que je met dans un hidden.
Du côté du serveur, je garde une trace de cette clé, un bête touch (moins gourmand que mettre en base) suffit.
Lors de la validation du formulaire, je regarde si le fichier (donc la clé) existe (un pti -e ) et s'il existe, je procède au traitement et supprime le fichier.
Si le fichier n'existe pas, c'est que le formulaire a déjà été utilisé et j'affiche le message qu'il faut.
De plus j'ai sur le serveur une entrée en crontab qui supprime toutes les clés non utilisées vieilles de plus de X heures (en général quand on a affiché une page avec le formulaire, on n'attend pas des heures avant de valider).
Cela permet de résoudre le cas du refresh accidentel, du back, mais aussi celui du refresh volontaire, du flood par (back+valide)*n, ou du bête script....
J'ai ce système depuis quelques années sur mon service de forums et ça tient bien la route.
# Facile
Posté par Sébastien Rohaut . Évalué à 2.
# Clé primaire
Posté par Damien Metzler . Évalué à 1.
Après si quelqu'un clique deux fois sur le bouton ou fait un refresh, tu auras une erreur quand tu essayeras d'insérer la ligne dans ta base. Il faut alors traiter cette erreur.
Pour moi, le truc des header qui redirige est vraiment pas top. Dans f.c.l.php, John Gallet explique régulièrement ce problème.
# Encore une autre astuce...
Posté par pir7 . Évalué à 1.
- Dans ton formulaire, ajoute un champ caché avec un timestamp (<input type="hidden" name="MyTime" value="<? time () ?>")
- Lorsque tu valide, récupère un autre timestamp dans une variable et compare :
<?php
if (!isset ($_SESSION["mytime"]) && $_SESSION["mytime"] >= $_POST["MyTime"])
{
// Pas encore enregistré ...
// Faire les traitements
// Récupérer le timestamp
$_SESSION["mytime"] = time ();
}
else
{
// Traitement déjà effectué...
}
?>
Voilà !
# chronologie
Posté par or zax . Évalué à 1.
tu créé une variable session, et à chaque fois que tu charge une page, tu l'indique, comme cela dans la page suivante, tu sais quel est la page précédente, le but est de faire un referer mais côté serveur, car on ne peut jamais compter sur le client.
Donc quand tu charge ta validation de formulaire, si le précédent est la page de validation et pas le formulaire normalement attendu, tu fais une un traitement gérant ton erreur selon ton humeur.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.