JeuWeb - Crée ton jeu par navigateur
Construction d'un formulaire - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : Construction d'un formulaire (/showthread.php?tid=7104)

Pages : 1 2 3 4 5


Construction d'un formulaire - Racktor - 09-08-2013

Bonjour à tous !

Bon j'ai fini mon script de combat, il est donc fonctionnel maintenant je fais l'interface pour le joueur.

Bhon alors le formulaire en lui-même pas franchement de souci sauf pour la récupération des données : imaginez que mon formulaire est aussi dynamique !

le joueur doit sélection les divisions qu'il souhaite engager dans le combat, le nombre de division maximum est fonction d'un niveau que le chef d'état major a. Donc on répète la même liste de division autant de fois que le niveau le permet logique... mais comment récupérer le résultat des listes ainsi crées ? on prend le niveau est on fait le chemin en sans inverse logiquement ?
une boucle qui récupère les variables POST...

Ensuite je crée une chaine de caractère du système de ce type la : 1-5-6-9
En gros les chiffres correspondent aux id des divisions utilisées, bhon après pour le traitement j’utilise la fonction qui permet de couper le chaine en fonction d'un caractère (ici -). C'est peut être pas trés propre mais bon ca marche -.-

Le problème c'est que cette chaine de caractère doit être vérifier : bha oui le joueur peut mettre plusieurs fois la même division ! alors comment détecter dans ce cas les doublons ?

Merci par avance pour le temps que vous consacrerez à mes questions.


RE: Construction d'un formulaire - Sephi-Chan - 09-08-2013

C'est difficile de t'aider avec si peu de matière.

Quelques éléments pourraient nous aider :
  • Une capture d'écran de ton interface ;
  • Le code HTML du formulaire ;
  • etc.



RE: Construction d'un formulaire - Racktor - 09-08-2013

(09-08-2013, 07:49 PM)Sephi-Chan a écrit : C'est difficile de t'aider avec si peu de matière.

Quelques éléments pourraient nous aider :
  • Une capture d'écran de ton interface ;
  • Le code HTML du formulaire ;
  • etc.
D'accord je vais poster mon code pas de soucis.

PS :

<form action="?action=attaque" method="post">
Vous souhaitez attaquer <select name="membre_attaque">
<?php
if (mysql_data_seek($sql_liste_membre,0))
{
while ($data1 = mysql_fetch_array($sql_liste_membre))
{
echo'<option value="'.$data1['pseudo'].'">'.$data1['pseudo'].'</option>';
}
}
?>
</select>
<br />
En utilisant en première ligne les divisions suivantes :
<br />
<?php
$count_dispo_division = 3;
$count = $count_dispo_division;
while ($count > 0)
{
?>
<select name="division_première_ligne_<?php echo $count ?>">
<?php
if (mysql_data_seek($sql_liste_division,0))
{
while ($data2 = mysql_fetch_array($sql_liste_division))
{
echo'<option value="'.$data2['id'].'">'.$data2['nom'].'</option>';
}
}
?>
</select>
<br />
<br />
<?php
$count--;
}
?>
<input type="hidden" name="nombre_division_max" value="<?php echo $count_dispo_division; ?>" />
<input type="submit" value="OK" />
</form>

Et pour le traitement bhaaa, pour l'instant je bidouille...


RE: Construction d'un formulaire - Racktor - 09-08-2013

Je n'arrive pas a récupérer les données de ma variable POST
if(isset($_GET['action']))
{
switch ($_GET['action'])
{
case 'attaque':
$count = $_POST['nombre_division_max'];
while($count > 0)
{
echo ${'$_POST["division_premiere_ligne_". $count .""]'};
$count--;
}
}
}
Ensuite je ne vois toujours pas comment détecter si une chaine de caractère comporte des doublons .


RE: Construction d'un formulaire - Xenos - 09-08-2013

Citation :Le problème c'est que cette chaine de caractère doit être vérifier : bha oui le joueur peut mettre plusieurs fois la même division ! alors comment détecter dans ce cas les doublons ?
1) Scinder la chaine de caractères
2) utiliser les algorithmes de tri de tableau
3) parcourir le tableau: si l'entrée N+1 est la même que la N alors il y a doublon

Code PHP :
<?php

$chaine
= "1-2-4-8-5-4-2-7-1-2";
$tableau = explode("-", $chaine); // la chaine est scindée suivant le caractère de séparation
sort($tableau);
var_dump($tableau);
$last = null;
foreach (
$tableau as $valeur)
{
if (
$valeur == $last)
throw new
Exception('Doublon: ' . $last . ' et ' . $valeur);
$last = $valeur;
}
echo(
'ok');
?>


Ca:
Code PHP :
<?php 
echo ${"$_POST['division_premiere_ligne_". $count ."']"};

Ce sera l'injection-party du week-end. Si la variable POST contient un nom de variable quelconque, la valeur de cette variable sera affichée. Si jamais la variable contient un mot de passe, ou une donnée sensible...

Pour le problème d'affichage:
Citation :<select name="division_première_ligne_<?php echo $count ?>">
vs
Citation :echo ${"$_POST['division_premiere_ligne_". $count ."']"};

Je te conseillerai de te restreindre aux caractères ASCII pour les noms (bien qu'il n'y ai pas de raison de fond de ne pas utiliser du utf-8), cela évitera les soucis d'un "e" qui devient un "è".


RE: Construction d'un formulaire - Racktor - 10-08-2013

Merci Xenos :good:

(09-08-2013, 11:56 PM)Xenos a écrit :
Citation :Le problème c'est que cette chaine de caractère doit être vérifier : bha oui le joueur peut mettre plusieurs fois la même division ! alors comment détecter dans ce cas les doublons ?
1) Scinder la chaine de caractères
2) utiliser les algorithmes de tri de tableau
3) parcourir le tableau: si l'entrée N+1 est la même que la N alors il y a doublon

Code PHP :
<?php
$chaine
= "1-2-4-8-5-4-2-7-1-2";
$tableau = explode("-", $chaine); // la chaine est scindée suivant le caractère de séparation
sort($tableau);
var_dump($tableau);
$last = null;
foreach (
$tableau as $valeur)
{
if (
$valeur == $last)
throw new
Exception('Doublon: ' . $last . ' et ' . $valeur);
$last = $valeur;
}
echo(
'ok');
?>
Humm ok il y a des trucs que je ne connais pas du genre trow new exception, je vais allez faire un tour sur la doc moi ...
(09-08-2013, 11:56 PM)Xenos a écrit : Ca:
Code PHP :
<?php 
echo ${"$_POST['division_premiere_ligne_". $count ."']"};

Ce sera l'injection-party du week-end. Si la variable POST contient un nom de variable quelconque, la valeur de cette variable sera affichée. Si jamais la variable contient un mot de passe, ou une donnée sensible...
je fais quoi alors ?
Au dela de cela je n'obtiens pas le résultat avec la concaténation alors que si je remplace par le numéro directement j'obtiens le bon résultat ...
Normalement j’aimerais obtenir : $_POST['division_premiere_ligne_1']
et pouvoir incrémenter le numéro pour sortir tous les résultats.

(09-08-2013, 11:56 PM)Xenos a écrit : Pour le problème d'affichage:
Citation :<select name="division_première_ligne_<?php echo $count ?>">
vs
Citation :echo ${"$_POST['division_premiere_ligne_". $count ."']"};

Je te conseillerai de te restreindre aux caractères ASCII pour les noms (bien qu'il n'y ai pas de raison de fond de ne pas utiliser du utf-8), cela évitera les soucis d'un "e" qui devient un "è".
Je me suis aperçu de la connerie, désolé ...


RE: Construction d'un formulaire - Sephi-Chan - 10-08-2013

Je pense que ce qu'il te faut c'est un formulaire comme ça :


<form action="..." method="POST">
<p>Cible : <input type="text" name="attack[target]" /></p>

<h2>Formation</h2>
<div>
<div>
Ligne 1 :
<select name="attack[lines][1]">
<option value="1">Lancier</option>
<option value="2">Épéiste</option>
<option value="3">Cavalier</option>
</select>
</div>
<div>
Ligne 2 :
<select name="attack[lines][2]">
<option value="1">Lancier</option>
<option value="2">Épéiste</option>
<option value="3">Cavalier</option>
</select>
</div>
</div>

<p><input type="submit" value="Attaquer !" /></p>
</form>

Et côté PHP, tu recevras dans $_POST['attack'] un hash de la forme suivante :


array(
'target' => 'Fooo',
'lines' => array(
'1' => '3',
'2' => '2'
)
);

C'est quand même bien plus pratique à traiter. Et pour savoir s'il y a un doublon, tu as juste à comparer la taille du tableau de toutes les divisions choisies ; dans mon cas 3 (en première ligne) et 2 (en deuxième ligne) à son équivalent dédoublonné : si ça ne correspond pas, c'est qu'il y avait des doublons.

Ça se fait simplement en faisant :


$selected_ids = array_values($_POST['attack']['lines']);
$has_duplicates = count($selected_ids) != count(array_unique($selected_ids));



RE: Construction d'un formulaire - Xenos - 10-08-2013

Citation :echo ${'$_GET["division_premiere_ligne_". $count .""]'}
La chaine est entourée de guillemets simples ' ' et donc, au niveau de $count, ce doit être des guillemets simples, sinon, php ne fait rien du tout et affiche, tel quel " . $count . ".

Ensuite, ${...} va chercher la variable dont le nom est '...'. Ici, le nom utilisé à la place des ... est '$_POST[]', donc php cherche une variable dont le nom est $_POST[], autrement dit, il ne cherche pas $_POST[] (variable dont le nom est _POST[]) mais $$_POST[].

La syntaxe que tu cherchais est:
Code PHP :
<?php 
echo $_POST["division_premiere_ligne_". $count]

Ici, PHP cherche bien la variable $_POST[] avec le nom de clef "division_premiere_ligne_". $count qui est une chaine de caractère composée d'une constante littérale (gauche) et de la valeur d'une variable (droite).

Pour l'injection, le principe est simple:
OWASP a écrit :Avant de faire n'importe quel traitement à une donnée entrante, il faut la vérifier par le biais d'une "whitelist".

En d'autres mots, avant de faire le moindre test ou manipulation d'une entrée ($_POST, $_GET, $_COOKIE, $_FILE(S?), headers HTTP, voire même les données issues de ton propre SQL ...) il faut les vérifier en ayant une liste de valeurs autorisées. La donnée doit être sur la liste des valeurs autorisées, sinon, elle doit être refusée. L'approche "blacklist" (lister les valeurs interdites et autoriser tout le reste) est souvent source de failles, l'approche whitelist est plus sécurisée.
Dans l'exemple précédent, avec ${...}, la valeur de ... venait directement du client (c'était la valeur de ton $_POST), donc je pouvait mettre n'importe quoi à la place des ... et voir la valeur de n'importe quelle variable PHP du serveur.

Il te faut donc d'abord vérifier que les valeurs de ton $_POST['attack'] sont toutes recevables et valides avant de les traiter. Pour "target", je ne sais pas quelle est ta whitelist, mais pour les "lines", je pense que tu peux transformer chaque valeur en entier, avec un cast (int), puis vérifier qu'elle est positive strictement et qu'elle ne dépasse pas la borne maximale (3 dans l'exemple précédent). Tu peux aussi faire une liste brute (array(1,2,3)) et vérifier que chaque valeur est bien strictement dedans (attention, '3' !=== 3 à cause du typage différent).


RE: Construction d'un formulaire - Racktor - 10-08-2013

(10-08-2013, 11:45 AM)Xenos a écrit :
Citation :echo ${'$_GET["division_premiere_ligne_". $count .""]'}
La chaine est entourée de guillemets simples ' ' et donc, au niveau de $count, ce doit être des guillemets simples, sinon, php ne fait rien du tout et affiche, tel quel " . $count . ".

Ensuite, ${...} va chercher la variable dont le nom est '...'. Ici, le nom utilisé à la place des ... est '$_POST[]', donc php cherche une variable dont le nom est $_POST[], autrement dit, il ne cherche pas $_POST[] (variable dont le nom est _POST[]) mais $$_POST[].

La syntaxe que tu cherchais est:
Code PHP :
<?php 
[quote='Xenos' pid='120782' dateline='1376127946']
echo
$_POST["division_premiere_ligne_". $count]

Ici, PHP cherche bien la variable $_POST[] avec le nom de clef "division_premiere_ligne_". $count qui est une chaine de caractère composée d'une constante littérale (gauche) et de la valeur d'une variable (droite).
Oki une erreur bête en somme ...
(10-08-2013, 11:45 AM)Xenos a écrit : Pour l'injection, le principe est simple:
OWASP a écrit :Avant de faire n'importe quel traitement à une donnée entrante, il faut la vérifier par le biais d'une "whitelist".

En d'autres mots, avant de faire le moindre test ou manipulation d'une entrée ($_POST, $_GET, $_COOKIE, $_FILE(S?), headers HTTP, voire même les données issues de ton propre SQL ...) il faut les vérifier en ayant une liste de valeurs autorisées. La donnée doit être sur la liste des valeurs autorisées, sinon, elle doit être refusée. L'approche "blacklist" (lister les valeurs interdites et autoriser tout le reste) est souvent source de failles, l'approche whitelist est plus sécurisée.
Dans l'exemple précédent, avec ${...}, la valeur de ... venait directement du client (c'était la valeur de ton $_POST), donc je pouvait mettre n'importe quoi à la place des ... et voir la valeur de n'importe quelle variable PHP du serveur.

Il te faut donc d'abord vérifier que les valeurs de ton $_POST['attack'] sont toutes recevables et valides avant de les traiter. Pour "target", je ne sais pas quelle est ta whitelist, mais pour les "lines", je pense que tu peux transformer chaque valeur en entier, avec un cast (int), puis vérifier qu'elle est positive strictement et qu'elle ne dépasse pas la borne maximale (3 dans l'exemple précédent). Tu peux aussi faire une liste brute (array(1,2,3)) et vérifier que chaque valeur est bien strictement dedans (attention, '3' !=== 3 à cause du typage différent).
OK j'en avais entendu parler mais bon pour moi c'étais plus de l'optimisation...
Pour le texte j'ai cette fonction assez classique :
Code :
function form($valeur)
{
    $valeur = (!get_magic_quotes_gpc()) ? addslashes($valeur) : $valeur;
    $valeur=trim(htmlspecialchars($valeur));
    return $valeur;
}
mais pour les données numériques j'ai par exemple dans le code du forum des int un peu partout avant les requêtes SQL. Dans mon jeu j'ai un système de détection de manipulation d'URL basique (j'ai oublier de temps en temps de vérifier le format il me semble ConfusediffleSmile mais si le joueur tombe sur quelque chose qui ne lui appartient pas il est avertit d'un possible tentative de manipulation d'URL et j'ai un rapport dans ma zone admin Et au bout de plusieurs je peux le suspendre.

Pour la white list, il faut que je repense mon code mais logiquement je pense utiliser un ensemble de condition dans un if. Bon déja il faut que je réutilise ce que tu m'as donné pour hasher et vérifier : je peux vérifier s'il l'entré est un nombre strictement positif et ensuite s'il n'y a pas de doublon.

Re-merci en tout cas.

(10-08-2013, 11:05 AM)Sephi-Chan a écrit : Je pense que ce qu'il te faut c'est un formulaire comme ça :


<form action="..." method="POST">
<p>Cible : <input type="text" name="attack[target]" /></p>

<h2>Formation</h2>
<div>
<div>
Ligne 1 :
<select name="attack[lines][1]">
<option value="1">Lancier</option>
<option value="2">Épéiste</option>
<option value="3">Cavalier</option>
</select>
</div>
<div>
Ligne 1 :
<select name="attack[lines][2]">
<option value="1">Lancier</option>
<option value="2">Épéiste</option>
<option value="3">Cavalier</option>
</select>
</div>
</div>

<p><input type="submit" value="Attaquer !" /></p>
</form>

Et côté PHP, tu recevras dans $_POST['attack'] un hash de la forme suivante :


array(
'target' => 'Fooo',
'lines' => array(
'1' => '3',
'2' => '2'
)
);

C'est quand même bien plus pratique à traiter. Et pour savoir s'il y a un doublon, tu as juste à comparer la taille du tableau de toutes les divisions choisies ; dans mon cas 3 (en première ligne) et 2 (en deuxième ligne) à son équivalent dédoublonné : si ça ne correspond pas, c'est qu'il y avait des doublons.

Ça se fait simplement en faisant :


$selected_ids = array_values($_POST['attack']['lines']);
$hasDuplicates = count($selected_ids) != count(array_unique($selected_ids));
Haaaaaaaaaaaa pas bêteeeee !
Me disait aussi qu'un array pouvait servir mais je ne voyais pas comment. Après coup c'est logique mais faut y penser.
Si je comprends bien tu compare la taille entre l'array que tu as et l'array dédoublonné, si c'est différent il y a des doublons, logique ...

Par contre comme je suis dans la logique de vérification je n'ai juste qu'a englober le post d'un int non ?


RE: Construction d'un formulaire - Xenos - 10-08-2013

Attention, optimisation n'est pas sécurité. Un site peut parfaitement marcher, sans être optimisé, mais il ne devrait pas être mis en ligne s'il n'est pas sécurisé. Par exemple:
Code PHP :
<?php 
echo $_GET['injection_grave'];
Si j'envoie à quelqu'un un lien avec ...?injection_grave=<script>alert(document.cookie);</script> alors cette personne verra apparaitre une pop-up qui affichera ses cookies. De là à modifier un peu le lien pour que ce cookie me soit envoyé, il n'y a qu'un pas. Et ayant le cookie de session, je peux me connecter à son compte sur ce site.
Donc, optimisation, on peut s'en ficher, mais sécurité, on ne devrait pas; la faille pouvant toucher juste le client (comme ici), ou juste le serveur (comme ton $$_POST) ou les deux.

Ne vérifie pas les données au moment de les utiliser: vérifies-les une bonne fois pour toute dès le début. Cela t'évitera des oublis, et cela limitera les risques.
Il me semble que magic quotes a disparu des nouvelles versions PHP.

Code PHP :
<?php 
(int)$_POST['attack']['lines'][$i]
Oui.
Mais attention: cast en int avant de vérifier les doublons, sinon:
Code :
array('#', '$');
Cet array n'a pas de doublons, mais une fois casté en int, il devient array(0,0) et là, on a un doublon (d'où l'intérêt de checker les données d'entrée dès le début et non au moment exact de leur utilisation).