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


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

Si on génère un doublon après avoir casté des caractères de toute façon interdits, il y a de toute façon un problème (les caractères interdits).

Je pense qu'il faut développer dans un style fail fast : arrêter le script le plus vite possible en cas de soucis et ne pas essayer de réparer les problèmes.

Si tu veux t'assurer de la bonne forme des données. Tu peux les vérifier et les convertir.


$selected_ids = array(1, 2, '3', '#', 4, 4);
$sane_selected_ids = array_filter($selected_ids, 'is_numeric'); // array(1, 2, '3', 4, 4)
$cast_selected_ids = array_map('intval', $sane_selected_ids); // array(1, 2, 3, 4, 4)
$unique_selected_ids = array_unique($cast_selected_ids); // array(1, 2, 3, 4)

Bien sûr, ça fait de nombreux traitement. Ça ne devrait pas poser de problème sur de faibles volumes.
Et après il faut bien sûr vérifier que l'utilisateur possède bien chacune de ces divisions !


Quand je vois ce genre de choses, je suis bien content d'utiliser un framework ! C'est tellement ennuyeux, répétitif et sans aucune valeur ajoutée !


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

(10-08-2013, 01:34 PM)Sephi-Chan a écrit : Si on génère un doublon après avoir casté des caractères de toute façon interdits, il y a de toute façon un problème (les caractères interdits).

Je pense qu'il faut développer dans un style fail fast : arrêter le script le plus vite possible en cas de soucis et ne pas essayer de réparer les problèmes.

Si tu veux t'assurer de la bonne forme des données. Tu peux les vérifier et les convertir.


$selected_ids = array(1, 2, '3', '#', 4, 4);
$sane_selected_ids = array_filter($selected_ids, 'is_numeric'); // array(1, 2, '3', 4, 4)
$cast_selected_ids = array_map('intval', $sane_selected_ids); // array(1, 2, 3, 4, 4)
$unique_selected_ids = array_unique($cast_selected_ids); // array(1, 2, 3, 4)

Bien sûr, ça fait de nombreux traitement. Ça ne devrait pas poser de problème sur de faibles volumes.
Et après il faut bien sûr vérifier que l'utilisateur possède bien chacune de ces divisions !


Quand je vois ce genre de choses, je suis bien content d'utiliser un framework ! C'est tellement ennuyeux, répétitif et sans aucune valeur ajoutée !
Alors logiquement j'arrive a cela :

if(isset($_POST['attack']))
{
$selected_ids = array_values($_POST['attack']['lines']);
$sane_selected_ids = array_filter($selected_ids, 'is_numeric');
$cast_selected_ids = array_map('intval', $sane_selected_ids);
$hasDuplicates = count($cast_selected_ids) != count(array_unique($cast_selected_ids));

if(empty($hasDuplicates))
{
$count = $_POST['nombre_division_max'];
echo $_POST['attack']['target'].'<br />';
while ($count > 0)
{
echo $_POST['attack']['lines'][$count].'<br />';
$count--;
}
}
else
echo 'Vous avez fait une erreur ! nom de gu, d\'nom de gu';
}
Ca marche au moins j’espère ne rien oublier ...
PS: j'ai un pb avec un # !
j'ai ajouté un champ a ma liste pour permettre au joueur de ne sélectionner aucune division !

<option value="#">Aucune</option>
sauf que le retraitement n'enlève pas le # ...


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

Je ne comprends pas trop. A quoi sert le code que tu as rajouté ? Le but de ton script n'est-il pas de faire des traitements ?
  • C'est au serveur de savoir le nombre de divisions autorisées, pas au client ;
  • Tu ne contrôles pas si le joueur a engagé plus de divisions que ce qui est autorisé ;
  • Tu ne contrôles pas si les divisions engagées sont bien disponibles pour le joueur ;
  • N'utilises pas empty($has_duplicates) mais directement $has_duplicates ;


(10-08-2013, 02:42 PM)Racktor a écrit : PS: j'ai un pb avec un # !
j'ai ajouté un champ a ma liste pour permettre au joueur de ne sélectionner aucune division !

<option value="#">Aucune</option>
sauf que le retraitement n'enlève pas le # ...

Tu as dû mal faire quelque chose, mon script l'enlève avec le array_filter. La variable saine est dans $cast_selected_ids. Si tu utilises les données de $_POST, elles n'ont pas été assainies.
Par ailleurs, pourquoi mettre un # plutôt que rien du tout (<option value="">Aucune</option>)?


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

(10-08-2013, 03:05 PM)Sephi-Chan a écrit : Je ne comprends pas trop. A quoi sert le code que tu as rajouté ? Le but de ton script n'est-il pas de faire des traitements ?
la logique primaire du truc, c'est de transformer des données séparer qui sont envoyées par le formulaire en une chaine du type 1-2-5-6 et de vérifier si c'est correcte pour enregistrer dans la BDD.

(10-08-2013, 03:05 PM)Sephi-Chan a écrit :
  • C'est au serveur de savoir le nombre de divisions autorisées, pas au client ;
  • Tu ne contrôles pas si le joueur a engagé plus de divisions que ce qui est autorisé ;
  • Tu ne contrôles pas si les divisions engagées sont bien disponibles pour le joueur ;
Mais si je vérifie je vais devoir générer des requêtes SQL, non ?
multiplier par le nombre de division a vérifier, rolala les ressources que ca va pomper ...

(10-08-2013, 03:05 PM)Sephi-Chan a écrit :
  • N'utilises pas empty($hasDuplicates) mais directement $hasDuplicates ;
  • Oki j'ai modifié

    (10-08-2013, 02:42 PM)Racktor a écrit : PS: j'ai un pb avec un # !
    j'ai ajouté un champ a ma liste pour permettre au joueur de ne sélectionner aucune division !

    <option value="#">Aucune</option>
    sauf que le retraitement n'enlève pas le # ...

    Tu as dû mal faire quelque chose, mon script l'enlève avec le array_filter. La variable saine est dans $cast_selected_ids. Si tu utilises les données de $_POST, elles n'ont pas été assainies.
    Par ailleurs, pourquoi mettre un # plutôt que rien du tout (<option value="">Aucune</option>)?
    Ha oui c'est vrai , je vais changer tout ca. Je vais trop vite et je passe au dessus de truc tout bête ...

    Merci pour l'aide


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

    Tu dois tout contrôler. Ce n'est pas si coûteux que ça. Un serveur SQL peut faire plein de choses très vite. Il ne faut pas avoir peur de faire des requêtes.

    Le bon nombre de requêtes SQL par page, c'est le nombre de requête SQL dont tu as besoin pour faire ton traitement. Le nombre importe moins que la complexité des requêtes. Une requête du type SELECT * WHERE id = X; est très rapide (si la colonne requêtée est indexée).

    Ces chiffres sont totalement empiriques, mais une page d'affichage peut bien produire une dizaine de requête SQL, et une page d'action (appelée moins souvent et qui va modifier des choses) peut bien faire une trentaine de requêtes : ça ne pose généralement aucun problème.


    Après, il faut le faire intelligemment. Ici, tu as au moins besoin de deux requêtes : une pour aller chercher le niveau du joueur courant (et donc le nombre de lignes autorisées). Je suppose que tu fais déjà cette requête sur toutes les pages pour avoir les informations du joueur courant.

    Ensuite, pour les divisions autorisées, tu n'as pas besoin de faire une requête par division, tu peux faire une requête qui sélectionne les IDs des divisions du joueur. Un SELECT id FROM divisions WHERE player_id = X; n'est pas très coûteux.

    Et une fois que tu as ces identifiants, tu peux les comparer à ceux données par l'utilisateur :



    $selected_ids = array(1, 2); // Le tableau bien filtré qu'on a créé tout à l'heure.
    $allowed_ids = array(1, 2, 3); // Ce qui te vient de la requête SQL mentionnée plus haut.
    $union = array_unique(array_merge($selected_ids, $allowed_ids)); // L'union des deux ensembles, sans doublons.
    $allIdsAreAllowed = count($allowed_ids) == count($union);

    Si le joueur a mis l'ID d'une division qu'il ne possède pas (disons que $selected_ids = array(1, 2, 4)), alors l'union contiendra 4 éléments (1, 2, 3, 4), donc plus que les 3 autorisées (1, 2, 3). On saura donc qu'il a essayé de tricher.


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

    Je dirai même que dès l'instant où la connexion est établie, le nombre de requêtes n'est plus vraiment pertinent, la connexion elle-même étant (d'après mes souvenirs sur les mutualisés ovh) assez longue face à une simple requête SELECT.

    Citation :Le nombre importe moins que la complexité des requêtes.
    Là, je ne suis pas d'accord: ayant fait quelques essais sur ECLERD à l'époque, je peux affirmer que 1 requête simple (selection d'une seule ville puis simulation de cette ville, et enfin sauvegardée en BDD) exécutée 100 fois est bien plus lent qu'une requête plus générale exécutée 1 fois (simuler 100x 1 ville oest nettement plus long que simuler 100 villes d'un coup).
    Après, y'a pas de règle en fait, puisqu'on peut faire des requêtes complexes très lourdes qui seront plus lentes que 100 requêtes simples (elles-mêmes plus lente qu'1 requête un peu plus compliquée mais exécutée une seule fois).

    De manière général, ne joues pas la "flemme" sur les points de sécurité / vérification, car le pirate ou le tricheur n'aura pas cette flemme Wink


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

    Je parle de requêtes légitimes : celles qui restent après avoir fait les optimisations de base telles que l'exemple de N + 1 que tu décris.


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

    Merci pour votre aide !

    Par contre Sephi j'ai une petit question : si dans l'array sélectionnant les "bonnes" divisions le joueur ne modifie pas la quantité mais l'id d'une division ? je sais pas si je me fais bien comprendre ...


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

    (13-08-2013, 12:42 PM)Racktor a écrit : Par contre Sephi j'ai une petit question : si dans l'array sélectionnant les "bonnes" divisions le joueur ne modifie pas la quantité mais l'id d'une division ? je sais pas si je me fais bien comprendre ...

    Reprenons le code :


    $selected_ids = array(1, 2); // Le tableau bien filtré qu'on a créé tout à l'heure.
    $allowed_ids = array(1, 2, 3); // Ce qui te vient de la requête SQL mentionnée plus haut.
    $union = array_unique(array_merge($selected_ids, $allowed_ids)); // L'union des deux ensembles, sans doublons.
    $all_ids_are_allowed = count($allowed_ids) == count($union);

    Puis testons-le avec une valeur invalide.

    Si tu as $allowed_ids = array(1, 2, 3) et $selected_ids = array(1, 2, 4), 4 n'est pas autorisé ! L'union des ID vaudra alors array(1, 2, 3, 4) et aura une cardinalité de 4. Puisque c'est supérieur à la cardinalité des ID autorisés, on sait qu'il y a tentative de tricherie.


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

    Attention: le message qui va suivre ne contient aucun intérêt.

    Soit S ($selected_ids) un tableau de N entiers, tous différents (cf filtrage précédent).
    Soit V ($allowed_ids) un tableau de P entiers, tous différents, supposés être les seuls autorisés.
    Soit f (array_merge) l'application qui à deux tableaux (T,U) associe un nouveau tableau V composé des éléments de T et de U (avec doublons)
    Soit g (array_unique) l'application qui à tout tableau T associe un nouveau tableau U composé des éléments de T sans doublons.
    Soit c (count) l'application qui à tout tableau T associe le nombre d'éléments n, entier, de ce tableau.
    Soit x un entier appartenant à S.

    Soit s et t deux tableaux tels quel:
    S = s + t
    Tout élément de s est dans V
    Tout élément de t n'est pas dans V
    t est composé de Nt éléments et peut être vide (Nt=0)
    s est composé de Ns éléments et peut être vide (Ns=0)
    N = Nt + Ns
    t et s peuvent être vides en même temps (alors, S est vide).

    Alors, g( f(S,V) ) = g( f(s+t,V) ) = g( f(t,V) + f(s,0) )
    f(s,0) = s
    f(t,V) = t + V car t et V sont disjoints
    Donc
    g(f(S,V)) = g( s + t + V) = g(t + V) car s est un sous tableau de V
    g(t + V) = t + V car t et V sont disjoints

    Donc
    c(g(f(S,V))) - c(V) = c(g(t + V)) - c(V) = c(t + V) - c(V) = c(t) + c(V) - c(V) car t et V disjoints
    D'où
    c(g(f(S,V))) - c(V) = c(t) = Nt

    Donc, count($allowed_ids) == count($union) si et seulement si tous les éléments de $selectid_ids se trouvent aussi dans $allowed_ids.


    (Ah, ça faisait longtemps \o/)