Calcul de la durée de remplissage d'un questionnaire

VaN
Mammouth du PHP | 1107 Messages

03 juin 2011, 16:47

Bonjour,

je travaille sur un projet de questionnaire, et j'ai besoin de savoir le temps qu'a mis l'utilisateur pour remplir le formulaire, du moment où il est généré au moment ou il inséré dans la base de données.

J'ai pensé juste stocker l'heure de génération du formulaire dans une variable de session, puis calculer la durée au moment de l'insertion en base, mais en réfléchissant un peu, il suffirait que l'utilisateur re-génère le formulaire (dans un nouvel onglet) juste avant de soumettre le premier pour que cela fausse tout.

Auriez-vous des idées sur comment récupérer cette durée, sans risque de 'triche' ?

ViPHP
AB
ViPHP | 5818 Messages

03 juin 2011, 18:26

Tu enregistre dans une variable de session une valeur que tu modifies, si elle existe déjà, à toute ouverture de cette même page.
Si cette variable n'est pas dans son état initial lors de la soumission c'est qu'il y a eu problème. Et tu supprime cette variable de session à la soumission du formulaire.
$_SESSION['form_ok'] = isset($_SESSION['form_ok'])? 0 : 1;

VaN
Mammouth du PHP | 1107 Messages

03 juin 2011, 18:48

Ok, donc j'utilise 2 variables de session, 1 pour stocker la date du chargement du formulaire, une autre pour savoir si le formulaire a été rechargé. Cela veut dire que pour l'application, tous les rechargements de formulaire sont interprétés comme des "tentatives de triche".

Aucun moyen pour une gestion un peu plus poussée ? Par exemple, interpréter chaque rechargement du formulaire comme un nouveau formulaire, totalement séparé du premier, et pouvoir gérer leur durées indépendamment ?

ViPHP
AB
ViPHP | 5818 Messages

03 juin 2011, 19:01

Cela veut dire que pour l'application, tous les rechargements de formulaire sont interprétés comme des "tentatives de triche".
Sauf si le formulaire a déjà été soumis auquel cas tu unset la variable et on repart à zero.

Sinon pourquoi veux-tu pouvoir gérer plusieurs formulaires identiques en même temps puisque c'est ce que tu souhaites éviter ?

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

03 juin 2011, 21:31

Pour réduire encore un peu les risques de collision, tu pourrais te baser sur le principe du CSRF, à savoir générer un token unique (une valeur aléatoire), que tu mets en champs caché dans le formulaire, et que tu utilises comme clé dans ta session pour stocker la date de génération.
// $sel est une chaine statique
$token = md5(date('u').$sel);

$_SESSION['form'][$token] = date('u');
...
<input type="hidden" name="token" value="<?php echo $token ?>" />
...
Du coup, si l'utilisateur regénère le formulaire, eh bien il aura un nouveau token de généré, et s'il soumet l'ancien formulaire, tu retrouveras bien la bonne date de génération
$token = $_POST['token'];
$date_generation = array_key_exists($token, $_SESSION['form']) : $_SESSION['form'][$token] : null;
Là, tu as la date de génération de ce formulaire, sans aucun soucis ;)
Et si la date n'existe pas en session, c'est qu'il a fait quelque chose de pas bien, mais il ne sera de toutes façon plus identifié ^^
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

VaN
Mammouth du PHP | 1107 Messages

10 juin 2011, 10:35

Pour réduire encore un peu les risques de collision, tu pourrais te baser sur le principe du CSRF, à savoir générer un token unique (une valeur aléatoire), que tu mets en champs caché dans le formulaire, et que tu utilises comme clé dans ta session pour stocker la date de génération.
// $sel est une chaine statique
$token = md5(date('u').$sel);

$_SESSION['form'][$token] = date('u');
...
<input type="hidden" name="token" value="<?php echo $token ?>" />
...
Du coup, si l'utilisateur regénère le formulaire, eh bien il aura un nouveau token de généré, et s'il soumet l'ancien formulaire, tu retrouveras bien la bonne date de génération
$token = $_POST['token'];
$date_generation = array_key_exists($token, $_SESSION['form']) : $_SESSION['form'][$token] : null;
Là, tu as la date de génération de ce formulaire, sans aucun soucis ;)
Et si la date n'existe pas en session, c'est qu'il a fait quelque chose de pas bien, mais il ne sera de toutes façon plus identifié ^^
Me revoilà. J'ai du mettre ce projet de côté une petite semaine. Mais je m'y remet. Effectivement Zeus, ta solution me semble pas mal, et je vais l'implémenter. Par curiosité, quel est le but d'ajouter un string statique à la fin du token ?

D'ailleurs je viens de tester date('u'), que je connaissais pas, et cela me génère "000000", pourtant, je suis en PHP 5.3. Une explication ?

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

10 juin 2011, 20:20

le problème c'est que tu confond u et U et ce n'est pas la même chose ;)
u Microsecondes (ajouté en PHP 5.2.2) Exemple : 654321
U Secondes depuis l'époque Unix (1er Janvier 1970, 0h00 00s GMT)
le u minuscule c'est le nombre de minuscule quand tu donne une date, la tu veux le nombre de seconde depuis l'an zéro unix (un timestamp quoi) c'est l'équivalent de la fonction time() ;)


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

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

11 juin 2011, 19:23

Par curiosité, quel est le but d'ajouter un string statique à la fin du token ?
Juste pour éviter que le token soit prévisible dans le cas où tu fais un simple md5(date('U'))
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer