En toute logique, le stockage à long terme ce ce jeton est totalement
inutile et c'est une logique inverse qu'il faut appliquer : on génère un
jeton d'autorisation qu'on stocke pour XX minutes (time out). S'il est
toujours valide quand la requête arrive, on exécuté la requête, sinon
elle a déjà été exécutée (ou est invalide car time-outée) et on ne
fait rien. Et c'est encore la base : on gère des listes de choses
autorisées, pas des listes de choses interdites.
Enfin bref, on gère manuellement une session quoi... (je disais quoi
récemment sur "répéter la même chose" ?)
Que ce soit par hidden, par paramètre dans un lien <a href>, par cookie
ou par pigeon voyageur, peu importe le mode de transmission, çà
marchera pareil.
En toute logique, le stockage à long terme ce ce jeton est totalement
inutile et c'est une logique inverse qu'il faut appliquer : on génère un
jeton d'autorisation qu'on stocke pour XX minutes (time out). S'il est
toujours valide quand la requête arrive, on exécuté la requête, sinon
elle a déjà été exécutée (ou est invalide car time-outée) et on ne
fait rien. Et c'est encore la base : on gère des listes de choses
autorisées, pas des listes de choses interdites.
Enfin bref, on gère manuellement une session quoi... (je disais quoi
récemment sur "répéter la même chose" ?)
Que ce soit par hidden, par paramètre dans un lien <a href>, par cookie
ou par pigeon voyageur, peu importe le mode de transmission, çà
marchera pareil.
En toute logique, le stockage à long terme ce ce jeton est totalement
inutile et c'est une logique inverse qu'il faut appliquer : on génère un
jeton d'autorisation qu'on stocke pour XX minutes (time out). S'il est
toujours valide quand la requête arrive, on exécuté la requête, sinon
elle a déjà été exécutée (ou est invalide car time-outée) et on ne
fait rien. Et c'est encore la base : on gère des listes de choses
autorisées, pas des listes de choses interdites.
Enfin bref, on gère manuellement une session quoi... (je disais quoi
récemment sur "répéter la même chose" ?)
Que ce soit par hidden, par paramètre dans un lien <a href>, par cookie
ou par pigeon voyageur, peu importe le mode de transmission, çà
marchera pareil.
De même je ne le stocke pas dans la
base car cela n'a effectivement aucun intérêt, mais dans la session. Par
contre je ne vois pas l'intérêt de mettre un timeout.
votre opinion sur les sessions,
Il n'y a pas que la gestion manuelle en dehors de tout mécanisme de PHP
De même je ne le stocke pas dans la
base car cela n'a effectivement aucun intérêt, mais dans la session. Par
contre je ne vois pas l'intérêt de mettre un timeout.
votre opinion sur les sessions,
Il n'y a pas que la gestion manuelle en dehors de tout mécanisme de PHP
De même je ne le stocke pas dans la
base car cela n'a effectivement aucun intérêt, mais dans la session. Par
contre je ne vois pas l'intérêt de mettre un timeout.
votre opinion sur les sessions,
Il n'y a pas que la gestion manuelle en dehors de tout mécanisme de PHP
En revanche, selon ce mécanisme là, il me semble qu'il vaudrait mieux
lier à la session un flag de type "formulaire machin déjà traité
correctement" et non un ID aléatoire, ce serait plus logique.
En revanche, selon ce mécanisme là, il me semble qu'il vaudrait mieux
lier à la session un flag de type "formulaire machin déjà traité
correctement" et non un ID aléatoire, ce serait plus logique.
En revanche, selon ce mécanisme là, il me semble qu'il vaudrait mieux
lier à la session un flag de type "formulaire machin déjà traité
correctement" et non un ID aléatoire, ce serait plus logique.
Tu as deux grands types de solutions, parfaitement combinables d'ailleurs.
1) le jeton unique, comme rappelé par exemple par D. Jourand dans ce
2) comprendre comment on doit utiliser une clef primaire ou une clef
Tu as deux grands types de solutions, parfaitement combinables d'ailleurs.
1) le jeton unique, comme rappelé par exemple par D. Jourand dans ce
2) comprendre comment on doit utiliser une clef primaire ou une clef
Tu as deux grands types de solutions, parfaitement combinables d'ailleurs.
1) le jeton unique, comme rappelé par exemple par D. Jourand dans ce
2) comprendre comment on doit utiliser une clef primaire ou une clef
Tu as deux grands types de solutions, parfaitement combinables d'ailleurs.
[ snip les bonnes solutions ]
Une troisieme: considérer qu'en recevant les données du formulaire, il
y a deux choses à faire
1) les traiter (ajout / retrait dans la base)
2) afficher quelque chose
Scinder ça en deux étapes
* la premiere fait le traitement, et fait une redirection sur la seconde
* la seconde fait uniquement un affichage.
Si l'utilisateur demande à réafficher la page, le traitement n'est pas relancé.
Ce genre de chose (à la hache):
[...]
header("Location: truc.php?etape¯fichersucces&nom=$nom")
Tu as deux grands types de solutions, parfaitement combinables d'ailleurs.
[ snip les bonnes solutions ]
Une troisieme: considérer qu'en recevant les données du formulaire, il
y a deux choses à faire
1) les traiter (ajout / retrait dans la base)
2) afficher quelque chose
Scinder ça en deux étapes
* la premiere fait le traitement, et fait une redirection sur la seconde
* la seconde fait uniquement un affichage.
Si l'utilisateur demande à réafficher la page, le traitement n'est pas relancé.
Ce genre de chose (à la hache):
[...]
header("Location: truc.php?etape¯fichersucces&nom=$nom")
Tu as deux grands types de solutions, parfaitement combinables d'ailleurs.
[ snip les bonnes solutions ]
Une troisieme: considérer qu'en recevant les données du formulaire, il
y a deux choses à faire
1) les traiter (ajout / retrait dans la base)
2) afficher quelque chose
Scinder ça en deux étapes
* la premiere fait le traitement, et fait une redirection sur la seconde
* la seconde fait uniquement un affichage.
Si l'utilisateur demande à réafficher la page, le traitement n'est pas relancé.
Ce genre de chose (à la hache):
[...]
header("Location: truc.php?etape¯fichersucces&nom=$nom")
Scinder ça en deux étapes
* la premiere fait le traitement, et fait une redirection sur la
seconde * la seconde fait uniquement un affichage.
Si l'utilisateur demande à réafficher la page, le traitement n'est pas
relancé.
Ce genre de chose (à la hache):
$etape = $_POST['etape'];
if (! $action) $action = "grille";
switch ($action) {
case "grille" :
print '<form action="truc.php?etape=traiter" method=POST>' print
'<input type=text name=nom size >'; ....
break;
case "traiter" :
$nom = $_POST['nom'];
ajouter_dans_base($nom)
header("Location: truc.php?etape¯fichersucces&nom=$nom") exit;
break;
case "afficher" :
$nom = $_GET['nom'];
print "<h1>Succes</h1> On a bien ajoute $nom"; break;
}
}
Scinder ça en deux étapes
* la premiere fait le traitement, et fait une redirection sur la
seconde * la seconde fait uniquement un affichage.
Si l'utilisateur demande à réafficher la page, le traitement n'est pas
relancé.
Ce genre de chose (à la hache):
$etape = $_POST['etape'];
if (! $action) $action = "grille";
switch ($action) {
case "grille" :
print '<form action="truc.php?etape=traiter" method=POST>' print
'<input type=text name=nom size >'; ....
break;
case "traiter" :
$nom = $_POST['nom'];
ajouter_dans_base($nom)
header("Location: truc.php?etape¯fichersucces&nom=$nom") exit;
break;
case "afficher" :
$nom = $_GET['nom'];
print "<h1>Succes</h1> On a bien ajoute $nom"; break;
}
}
Scinder ça en deux étapes
* la premiere fait le traitement, et fait une redirection sur la
seconde * la seconde fait uniquement un affichage.
Si l'utilisateur demande à réafficher la page, le traitement n'est pas
relancé.
Ce genre de chose (à la hache):
$etape = $_POST['etape'];
if (! $action) $action = "grille";
switch ($action) {
case "grille" :
print '<form action="truc.php?etape=traiter" method=POST>' print
'<input type=text name=nom size >'; ....
break;
case "traiter" :
$nom = $_POST['nom'];
ajouter_dans_base($nom)
header("Location: truc.php?etape¯fichersucces&nom=$nom") exit;
break;
case "afficher" :
$nom = $_GET['nom'];
print "<h1>Succes</h1> On a bien ajoute $nom"; break;
}
}
Le Fri, 15 Sep 2006 17:31:33 +0000, Michel Billaud a écrit :Scinder ça en deux étapes
* la premiere fait le traitement, et fait une redirection sur la
seconde * la seconde fait uniquement un affichage.
Si l'utilisateur demande à réafficher la page, le traitement n'est pas
relancé.
Cela ne résoud pas le problème : que se passe-t-il si le /refresh/ est
fait avec $action = "traiter" ? Les solutions proposés dans ce fil sont
justement là pour résoudre ce problème.
Le Fri, 15 Sep 2006 17:31:33 +0000, Michel Billaud a écrit :
Scinder ça en deux étapes
* la premiere fait le traitement, et fait une redirection sur la
seconde * la seconde fait uniquement un affichage.
Si l'utilisateur demande à réafficher la page, le traitement n'est pas
relancé.
Cela ne résoud pas le problème : que se passe-t-il si le /refresh/ est
fait avec $action = "traiter" ? Les solutions proposés dans ce fil sont
justement là pour résoudre ce problème.
Le Fri, 15 Sep 2006 17:31:33 +0000, Michel Billaud a écrit :Scinder ça en deux étapes
* la premiere fait le traitement, et fait une redirection sur la
seconde * la seconde fait uniquement un affichage.
Si l'utilisateur demande à réafficher la page, le traitement n'est pas
relancé.
Cela ne résoud pas le problème : que se passe-t-il si le /refresh/ est
fait avec $action = "traiter" ? Les solutions proposés dans ce fil sont
justement là pour résoudre ce problème.
Les trois solutions sont complémentaires, aucune ne résoud le problème
à elle toute seule.
- un bon contrôle des opérations sur la base est de toutes façons
indispensable, puisqu'il faut prévoir l'accès concurrent aux données
par plusieurs utilisateurs.
Les trois solutions sont complémentaires, aucune ne résoud le problème
à elle toute seule.
- un bon contrôle des opérations sur la base est de toutes façons
indispensable, puisqu'il faut prévoir l'accès concurrent aux données
par plusieurs utilisateurs.
Les trois solutions sont complémentaires, aucune ne résoud le problème
à elle toute seule.
- un bon contrôle des opérations sur la base est de toutes façons
indispensable, puisqu'il faut prévoir l'accès concurrent aux données
par plusieurs utilisateurs.
[Dernière intervention de ma part dans ce thread, je fatigue.]Les trois solutions sont complémentaires, aucune ne résoud le problème
à elle toute seule.
Je proteste, relisez la définition d'une clef primaire. Conseil : lisez
là "à l'envers" (i.e. ce qu'elle implique pour la table/relation et non
la manière de la choisir au niveau d'un rang).
- un bon contrôle des opérations sur la base est de toutes façons
indispensable, puisqu'il faut prévoir l'accès concurrent aux données
par plusieurs utilisateurs.
L'accès concurrentiel entre utilisateurs n'a rien à voir là dedans, même
si c'est un problème à gérer bien entendu.
Si c'est de l'INSERT, il suffit de choisir correctement ses clefs
uniques/primaires.
[Dernière intervention de ma part dans ce thread, je fatigue.]
Les trois solutions sont complémentaires, aucune ne résoud le problème
à elle toute seule.
Je proteste, relisez la définition d'une clef primaire. Conseil : lisez
là "à l'envers" (i.e. ce qu'elle implique pour la table/relation et non
la manière de la choisir au niveau d'un rang).
- un bon contrôle des opérations sur la base est de toutes façons
indispensable, puisqu'il faut prévoir l'accès concurrent aux données
par plusieurs utilisateurs.
L'accès concurrentiel entre utilisateurs n'a rien à voir là dedans, même
si c'est un problème à gérer bien entendu.
Si c'est de l'INSERT, il suffit de choisir correctement ses clefs
uniques/primaires.
[Dernière intervention de ma part dans ce thread, je fatigue.]Les trois solutions sont complémentaires, aucune ne résoud le problème
à elle toute seule.
Je proteste, relisez la définition d'une clef primaire. Conseil : lisez
là "à l'envers" (i.e. ce qu'elle implique pour la table/relation et non
la manière de la choisir au niveau d'un rang).
- un bon contrôle des opérations sur la base est de toutes façons
indispensable, puisqu'il faut prévoir l'accès concurrent aux données
par plusieurs utilisateurs.
L'accès concurrentiel entre utilisateurs n'a rien à voir là dedans, même
si c'est un problème à gérer bien entendu.
Si c'est de l'INSERT, il suffit de choisir correctement ses clefs
uniques/primaires.
Si c'est de l'INSERT, il suffit de choisir correctement ses clefs
uniques/primaires.
Quand y en a, et y en a pas toujours.
Contre-exemple, un site genre banque pour rire où il y a des
"virements" à faire d'un compte à un autre. On n'attribue pas un
identifiant a priori à chaque virement, donc si on reposte l'ordre de
virement (emetteur, destinataire, montant), c'est pas la vérification
SQL qui y peut quelque chose... Même remarque pour l'UPDATE.
La solution est alors le jeton pour évite de re-traiter un formulaire.
Si c'est de l'INSERT, il suffit de choisir correctement ses clefs
uniques/primaires.
Quand y en a, et y en a pas toujours.
Contre-exemple, un site genre banque pour rire où il y a des
"virements" à faire d'un compte à un autre. On n'attribue pas un
identifiant a priori à chaque virement, donc si on reposte l'ordre de
virement (emetteur, destinataire, montant), c'est pas la vérification
SQL qui y peut quelque chose... Même remarque pour l'UPDATE.
La solution est alors le jeton pour évite de re-traiter un formulaire.
Si c'est de l'INSERT, il suffit de choisir correctement ses clefs
uniques/primaires.
Quand y en a, et y en a pas toujours.
Contre-exemple, un site genre banque pour rire où il y a des
"virements" à faire d'un compte à un autre. On n'attribue pas un
identifiant a priori à chaque virement, donc si on reposte l'ordre de
virement (emetteur, destinataire, montant), c'est pas la vérification
SQL qui y peut quelque chose... Même remarque pour l'UPDATE.
La solution est alors le jeton pour évite de re-traiter un formulaire.