IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaScript Discussion :

Retrouver l'index d'un objet placé dans un array


Sujet :

JavaScript

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2014
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 24
    Points : 8
    Points
    8
    Par défaut Retrouver l'index d'un objet placé dans un array
    Bonjour,

    * J'ai une liste d'ID (un par client) et à chaque client est associé plusieurs marqueurs sur une carte leaflet.

    * Je parcours la base de donnée, trouve quel est le plus grand ID, et crée une markerMap (tableau à 2 dimensions) où je pourrai associer IDs et marqueurs :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    var markerMap = new Array( <?php include('get_maxId.php');?> ); // pour les IDs des clients
    for (i=0;i<markerMap.length;i++)
    	{
    	markerMap[i] = new Array(); // ici on mettra les IDs des marqueurs de chaque client (nombre indéterminé)
    };
    * Ensuite je récupère en base de données le nombre d'IDs et le nombre de marqueurs associés à chaque ID (qui est variable d'un client à l'autre) et fais 2 boucles imbriquées pour parcourir les IDs et leurs marqueurs associés :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    //php pour récupérer en bdd et qui retourne un objet JSON (accessible ds la boucle via data[i]), puis :
    for (var i = 0; i < data.length; i++) { // boucle sur les IDs
       var combien_marqueurs = data[i].combien_marqueurs;
       var pseudoId = data[i].id;
     
       for (var j = 1; j <= combien_stories; j++) { // boucle sur les marqueurs
       //... 
       }
    }
    *** Mon problème est dans cette 2ème boucle :
    Dans cette boucle, je crée les marqueurs et les rentre dans la markerMap pour pouvoir les manipuler ensuite :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    eval('markerMap[clientId]['+j+'] = marker');
    Tout va bien, le j est bien pris en compte. Mais, ensuite, j'utilise une fonction pour enregistrer la position des marqueurs dans la bdd lorsqu'ils sont déplacés sur la carte (on dragend) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    marker.on('dragend', function(event) {
    	var result = this.getLatLng();
    	var lati = result.lat;
    	var longi = result.lng;
    	$.post('set_position_marqueur.php', { marqueurId: j, latitude: lati, longitude: longi});
    });
    Et là, bien sûr, c'est le drame! Lorsqu'on drag un marqueur la 2ème boucle en j++ est finie depuis longtemps et je ne peux enregistrer en base que le dernier marqueur de chaque utilisateur. Bien sûr ça fonctionne si je met le numéro du marqueur en dur, mais j'aimerai éviter :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if (j==1){	marker.on('dragend', ... $.post('set_poi.php', { marqueurId: 1, latitude: lati, longitude: longi}); }
    if (j==2){	marker.on('dragend', ... $.post('set_poi.php', { marqueurId: 2, latitude: lati, longitude: longi}); } 3,4,5 etc.
    >>> QUESTION :
    Y a-t-il un moyen de retrouver depuis le marqueur sa place dans la markerMap afin de savoir si on est en train de manipuler le marqueur 1, le 2, le 3... Pour l'id du client, je me sers d'une variable session_id, donc pas de soucis.

    Je voudrais donc juste trouver markerMap[clientId][ça]
    parser le tableau? faire une sorte de tableau reverse (je l'avais fait en flash)? créer une autre var qui stocke la "vraie" valeur de j? ou autre?

    merci bcp!

  2. #2
    Expert éminent
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 094
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 094
    Points : 6 755
    Points
    6 755
    Par défaut
    À deux heures du mat' comme ça j'ai peut-être pas tout saisi mais j'ai l'intuition que tu as besoin de indexOf ou lastIndexOf.

    Et puis j'ai vu cette horreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    eval('markerMap[clientId]['+j+'] = marker');
    Je vois pas l'intérêt du eval ici. Toujours éviter eval quand on peut. Il y a des ressources sur ce site qui expliquent pourquoi, fais une petite recherche
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    markerMap[clientId][j] = marker;
    Ça marche pas simplement comme ça ?

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2014
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 24
    Points : 8
    Points
    8
    Par défaut
    Merci de t'intéresser à mon problème. A cette heure, on ne voit plus clair

    Effectivement eval ne servait à rien. Je l'avais cru utile en désespoir de cause alors que le problème venait d'ailleurs sûrement. Merci!

    C'est une question de sécurité c'est ça (injection de code) ? Si on ne peut s'en passer mais que les données ne viennent pas d'un champs input, c'est pas trop grave?
    Je fais des appels à la bdd après, mais j'ai fait des requêtes préparées (d'après ce que j'ai lu, ça évite les injections)

    Par ailleurs, merci pour indexOf ça va sûrement le faire! Par contre, je lis que c'est incompatible avec IE < 9...
    Il va peut-être falloir que je code en dur alors...

    Bonne nuit!

  4. #4
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2014
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 24
    Points : 8
    Points
    8
    Par défaut
    Merci pour indexOf, je ne savais pas que ça marchait pour les tableaux. J'ai fait ça et ça roule :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    marker.on('dragend', function(event) {
    	var result = this.getLatLng();
    	var lati = result.lat;
    	var longi = result.lng;
    	var marqueurId = markerMap[sessionId].indexOf(this); // sessionId = clientId en réalité // >>> OK mais pas sur IE8
    	$.post('set_position_marqueur.php', { marqueurId: marqueurId, latitude: lati, longitude: longi});
    });
    Alors pour IE8, j'ai tout essayé (y compris des boucles dans la boucle etc...), pas moyen de sauvegarder ce j de la boucle qqe part pour le retrouver ensuite... Sinon j'ai trouvé une réécriture de la fonction indexOf pour être compatible IE8, je ne sais pas si ça peut fonctionner.

    Mais j'aurais peut-être dû faire un tableau à base de propriétés?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    //A la place de : 
    markerMap[clientId][numéro du marker] = marker
    //Faire : 
    var markerMap[clientId]= [
            {
                'latitudeMarker1':'35.000000',
                'longitudeMarker1': '56.000798',
            },
            {
                'latitudeMarker2':'35.000000',
                'longitudeMarker2': '56.000798',
            }, etc....
    ];
    Aurais-ce été mieux? Sachant que je ne sais pas à l'avance le nombre de clients ni le nombre de markers par client, comment déclarer ça?

  5. #5
    Expert éminent
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 094
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 094
    Points : 6 755
    Points
    6 755
    Par défaut
    Le code de remplacement que tu as trouvé sur JDN s'appelle un polyfill. Il y en a un plus efficace et plus robuste sur le MDN.

    Pour eval je pense que tu confonds injections XSS et injections SQL. Ce n'est pas le même champ de bataille (si tu vois ce que je veux dire) : une XSS attaque le visiteur, une injection SQL attaque la base de données.
    Mais pour moi, eval c'est surtout un problème d'efficacité : normalement, tout le code source JavaScript est interprété avant l'exécution ; avec eval, le moteur d'exécution est obligé de rappeler l'interpréteur, ce qui peut causer un ralentissement.

    Le « tableau à base de propriétés » c'est aussi une bonne idée Mais pourquoi pas un objet anonyme tout simplement ? Tu peux le déclarer vide pour commencer :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    var markerMap[clientId] = {};
    Grâce à ça tu n'as pas besoin de connaître à l'avance le nombre de clients. Et après :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    markerMap[clientId].latitudeMarker1 = '35.000000';
    markerMap[clientId].longitudeMarker1 = '56.000798';
    markerMap[clientId].latitudeMarker2 = '35.000000';
    markerMap[clientId].longitudeMarker2 = '56.000798';
    // etc.
    Ou avec la syntaxe des crochets :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    markerMap[clientId]["latitudeMarker1"] = '35.000000';
    markerMap[clientId]["longitudeMarker1"] = '56.000798';
    markerMap[clientId]["latitudeMarker2"] = '35.000000';
    markerMap[clientId]["longitudeMarker2"] = '56.000798';
    // etc.
    Cette dernière syntaxe te permet de gérer dynamiquement tes noms de variables : faire des trucs du genre markerMap[clientId]["latitudeMarker" + j].

    Mais l'important c'est d'avoir des structures de données simples et cohérentes. En l'occurence, tu peux décider qu'un marqueur c'est un tableau à deux cases (latitude et longitude), ou alors un objet avec une propriété latitude et une propriété longitude. Et du coup, tu stockes des tableaux de marqueurs, ce qui ressemble donc à ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    markerMap[clientId] = [
      ['35.000000', '56.000798'], // marqueur 0
      ['35.000000', '56.000798'], // marqueur 1
    ];
    Ou

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    markerMap[clientId] = [
      { latitude: '35.000000', longitude: '56.000798' }, // marqueur 0
      { latitude: '35.000000', longitude: '56.000798' }, // marqueur 1
    ];
    Un peu comme tu as fait, mais la différence c'est que les noms de propriétés sont les mêmes ce qui est bien plus pratique !
    Et pour y accéder (suppose que tu as une variable markerId contenant 0 par exemple) :
    • si tu as choisi des tableaux à deux cases, markerMap[clientId][markerId][0] pour la latitude et markerMap[clientId][markerId][1] pour la longitude ;
    • sinon, simplement markerMap[clientId].latitude et markerMap[clientId].longitude.

    Quand j'ai à choisir une représentation de structures comme ici, en général je préfère des noms plutôt que des tableaux. C'est un peu plus long, mais tellement plus lisible

  6. #6
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 110
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 110
    Points : 44 929
    Points
    44 929
    Par défaut
    Bonjour,
    peut être n'ai je pas compris ton problème, mais je me risque.
    en utilisant un objet markerMap ={}, à la création des marker on initialise de telle sorte à avoir une liaison à "double sens"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    le_nouveau_marker.clientId = clientId;     // ajout propriété au marker
    le_nouveau_marker.clientIndex = i;         // si vraiment nécessaire
    markerMap[clientId].push( le_nouveau_marker);
    de telle sorte que tu peux obtienir directement sa position, si nécessaire.

    et dans ta fonction plus de soucis de récupération des données
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    marker.on('dragend', function(event) {
    	var result = this.getLatLng();
    	var lati   = result.lat;
    	var longi  = result.lng;
    	var client = this.clientId;    
    	var index  = this.clientIdIndex;    
    	// la suite...de ton besoin     
    });

  7. #7
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2014
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 24
    Points : 8
    Points
    8
    Par défaut
    Merci à tous les 2 pour ces réponses détaillées!!

    les XSS je ne connaissais pas effectivement, idem pour les polyfill. Je suis débutant et autodidacte, double peine Jusqu'à présent j'avais surtout fait de l'AS, et, au moment où je commençais à m'habituer à ce sublime et simple langage (10 lignes pour afficher une image) , paf, flash disparaît...

    Vos solutions sont très alléchantes et assez similaires il me semble. En réalité l'idée de la markerMap m'était venue d'un forum. Et ils utilisaient effectivement cette syntaxe : markerMap = {};
    Je me doutais vaguement qu'il s'agissait d'un objet "vide", mais ne savais pas trop quoi.

    Je mets sur résolu, car déjà l'indexOf m'a sauvé la mise.
    Et je fais les tests avec vos nouvelles idées. Là, pour l'instant je n'y arrive pas mais je vous tiens au courant.

  8. #8
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2014
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 24
    Points : 8
    Points
    8
    Par défaut
    Voilà ce que j'ai cru être la solution en m'inspirant de vos codes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    markerMap = {}; //Watilin je ne pars pas sur markerMap[clientId] = {};, car à l'endroit où je déclare clientId n'est pas encore défini
    for (i... { //boucle qui énumère les clients
    for (j... { //boucle qui énumère les markers PAR client	
    	marker.clientId = clientId;
    	marker.markerId = j;
    	markerMap[pseudoId][markerId].push(marker);
    }
    }
    mais ça ne vas pas. Je n'ai plus qu'un ptit marker qui s'affiche, la boucle stoppe...

  9. #9
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 110
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 110
    Points : 44 929
    Points
    44 929
    Par défaut
    Voici une façon d'implémenter tes objets
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    var client = ['Jean', 'Michel', 'Robert'];
    var marker = ['un', 'deux', 'trois', 'quatre'];
    var new_marker,
        markerMap = {};
    for( var i=0; i < client.length; i++){
      markerMap[client[i]] = [];
      for( k=0; k< marker.length; k++){
        new_marker = {};
        new_marker['nom']    = marker[k];
        new_marker['client'] = client[i];
        new_marker['index']  = k;
        markerMap[client[i]].push( new_marker);
      }
    }
    console.log(markerMap['Jean'][0]);
    regarde dans la console ce que cela donne.

  10. #10
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2014
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 24
    Points : 8
    Points
    8
    Par défaut
    merci à tous, je vais étudier ça de près.

    Je me permets un petit hors-sujet (c'est plus en rapport avec le php) parce que 2 choses me paraissent complètement incompréhensibles. Pardon par avance pour la complexité des explications :



    1. Utilisation des require require_once include include_once
    *J'ai créé 2 petits fichiers php qui vont chercher chacun une petite info en base à un moment t :
    get_maxID.php et get_combienMarkers.php
    *Je les include dans cet ordre dans le js de la page principale index.php
    *Dans ces fichiers, il y a également des include d'un autre fichier php qui gère la connexion à la bdd : baseconnex.php
    **Et voilà, si, dans get_maxId je mets require_once('baseconnex.php) et, dans get_combienMarkers.php je mets require('baseconnex.php) tout roule!
    **Idem si je mets include partout. Par contre :
    **Si je fais l'inverse (require en 1er et require_once en 2nd), ça plante!
    Y a-t-il des règles sur les include qui m'échappent?

    Encore plus bizarre, si je fais l'inverse (code qui plante) mais que je commente la ligne js qui appelle le php, ça plante aussi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    //nombreMarkers= <?php include('get_combienMarkers.php'); ?>;
    ça ça me dépasse! Comment une ligne commentée peut-elle faire planter le code? (si je supprime la ligne, tout roule!)




    2. Je veux récupérer dans des variables "globales" les sessionId et sessionPseudo des clients :
    ce code marche :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <?php if(isset ($_SESSION['id']) && isset ($_SESSION['pseudo'])){if( $_SESSION['id']!="" && $_SESSION['pseudo']!=""){ ?>
    var sessionId = <?php echo htmlentities($_SESSION['id'], ENT_QUOTES, 'UTF-8'); ?>;
    <?php }} ?>
    celui-là fait tout planter :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    <?php if(isset ($_SESSION['id']) && isset ($_SESSION['pseudo'])){if( $_SESSION['id']!="" && $_SESSION['pseudo']!=""){ ?>
    var sessionId = <?php echo htmlentities($_SESSION['id'], ENT_QUOTES, 'UTF-8'); ?>;
    var sessionPseudo = <?php echo htmlentities($_SESSION['pseudo'], ENT_QUOTES, 'UTF-8'); ?>;
    <?php }} ?>
    ???
    Alors qu'à un autre endroit de la page, j'ai pu faire fonctionner sans problème un petit message de bienvenue:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <?php echo 'Bonjour '.htmlentities($_SESSION['pseudo'], ENT_QUOTES, 'UTF-8'); ?>
    Si j'enlève les htlentities, même sentence... la var sessionPseudo n'est pas déclaré ailleurs... je ne comprends vraiment plus...




    Merci à vous. Si une âme charitable a une idée pour ces 2 mystères je suis preneur

  11. #11
    Expert éminent
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 094
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 094
    Points : 6 755
    Points
    6 755
    Par défaut
    Citation Envoyé par remlev94 Voir le message
    Et voilà, si, dans get_maxId je mets require_once('baseconnex.php) et, dans get_combienMarkers.php je mets require('baseconnex.php) tout roule!
    […]
    Par contre :
    **Si je fais l'inverse (require en 1er et require_once en 2nd), ça plante!
    Ok ça plante, mais ça dit quoi ? J'aurais plutôt pensé que ça planterait en faisant d'abord require_once puis require, parce que ça mènerait à des redéclarations de fonctions ou de classes (Fatal error: Cannot redeclare machin truc…).

    Explore la doc ça peut peut-être t'aider.

    Sinon je pense que le problème se situe plutôt au niveau du contexte de variables à l'endroit où tu fais la seconde inclusion : avec require_once, le fichier n'est pas ré-inclus, or tu en as à nouveau besoin car tu es dans le contexte locale d'une fonction. Ou un truc comme ça.

    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    //nombreMarkers= <?php include('get_combienMarkers.php'); ?>;
    ça ça me dépasse! Comment une ligne commentée peut-elle faire planter le code? (si je supprime la ligne, tout roule!)
    Parce qu'elle n'est pas commentée

    Explication rapide. l'interpréteur PHP a deux modes de fonctionnement : le mode texte, et le mode analyse.
    Quand il commence, il est en mode texte. Tout ce qu'il lit, il le crache aussitôt vers la sortie HTTP, et ça lui fait pas grand chose que ce soit du code HTML, JavaScript ou autre. Il envoie sans regarder.

    Par contre, quand il rencontre le bout de code <?php, là il passe en mode analyse, et il exécute le code PHP. Et il repasse en mode texte quand il trouve un ?>.

    Alors que se passe-t-il dans ton cas ? Eh bien, au moment où il arrive sur ta « ligne commentée », l'interpréteur est simplement en mode texte, du coup il envoie le texte //nombreMarkers=, et là il passe en mode analyse et il fait l'include !

    Je pense que, comme beaucoup de débutants, tu fais l'amalgame entre les contextes d'exécution de PHP et de JS. Ils ne tournent pas au même moment, et pas sur la même machine. Il y a des kilomètres de câbles entre les deux ! (et peut-être même un ou deux satellites)


    2. Je veux récupérer dans des variables "globales" les sessionId et sessionPseudo des clients :
    ce code marche :
    celui-là fait tout planter :
    Encore une fois, tu ne nous donnes pas d'infos sur les éventuels messages d'erreur. Et d'ailleurs, ça plante côté PHP ou JS ?

    Alors qu'à un autre endroit de la page, j'ai pu faire fonctionner sans problème un petit message de bienvenue:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <?php echo 'Bonjour '.htmlentities($_SESSION['pseudo'], ENT_QUOTES, 'UTF-8'); ?>
    Eh oui car ça générait du HTML et pas du JS. Et pour sessionId, ça marche par hasard car JS arrive à le récupérer sous la forme d'un nombre. Mais pour le pseudo, JS te sort une erreur du genre ReferenceError: Bidule is not defined (au fait, tu sais comment voir tes messages d'erreur en JS ?) car il ne comprend pas ce mot qui ne correspond à aucun mot-clé du langage, et qui n'est pas dans la table des variables. Fais-en une chaîne en rajoutant des guillemets autour

  12. #12
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2014
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 24
    Points : 8
    Points
    8
    Par défaut
    Alors là chapeau, super réponse. ça enlève le voile sur pleins de trucs! Et c'est super clair.

    *Ce que j'entends par planter est que la page affichée sur le navigateur comporte des éléments manquants ou est inopérationnelle.

    *Effectivement, je ne suis pas un pro pour voir les messages d'erreur. Dans le cas d'un gros pb php, j'ai wamp qui me lance un beau message sur fond rouge. Idem pour pdo, j'ai activé les messages d'erreur. Pour le js, je ne sais pas trop me servir de la console. Je suis avec ffox, j'arrive à voir les POST et GET, mais pour le reste c'est flou.

    *Je regarde la source depuis ffox.
    Par exemple, pour le 'plantage require_once', la source ne contenait plus rien après cette ligne.

    Par contre, pour le 'plantage'
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    <?php if(isset ($_SESSION['id']) && isset ($_SESSION['pseudo'])){if( $_SESSION['id']!="" && $_SESSION['pseudo']!=""){ ?>
    var sessionId = <?php echo htmlentities($_SESSION['id'], ENT_QUOTES, 'UTF-8'); ?>;
    var sessionPseudo = <?php echo htmlentities($_SESSION['pseudo'], ENT_QUOTES, 'UTF-8'); ?>;
    <?php }} ?>
    la source contient tout. J'ai même :
    var sessionId = 31;
    var sessionPseudo = vinz;
    C'est-à-dire exactement ce que je voulais...

    Je comprends ce que tu dis sur le fait que j'ai eu du bol avec le typeof number et qu'avec pseudo en string, c'est moins cool.
    J'ai donc mis des guillemets comme t'as dit et tout refonctionne! merci

    *Juste un dernier conseil si tu veux bien : dans quel cas utiliser ou ne pas utiliser htmlentities? Je crois que c'est un problème de sécurité. Là, sessionId et sessionPseudo sont inscrits dans un cookie, donc en aucun cas rentrés par un utilisateur. Mais il est facile, d'après ce que j'ai compris, pour qqn de connaisseur et malveillant, de lire ce cookie non crypté.
    >> Dans le html, pour le message d'accueil 'Bonjour vinz', htmlentities est une bonne idée ?
    >> Dans le JS, est-ce mieux de faire simplement : var sessionId = <?php echo $_SESSION['id']; ?>; ?

  13. #13
    Expert éminent
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 094
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 094
    Points : 6 755
    Points
    6 755
    Par défaut
    htmlentities est une généralisation de htmlspecialchars. En plus de « sécuriser » la chaîne, elle résoud aussi les problèmes d'encodage courants (mais pas tous), en remplaçant par exemple é par &eacute;. Ce n'est pas nécessaire si tu t'es assuré que l'encodage réel (dans les options de ton éditeur de texte) correspond à l'encodage déclaré (dans une <meta> et dans le Content-Type envoyé par ton serveur).

    En revanche, la part de sécurité assurée par htmlspecialchars est nécessaire quand la chaîne peut contenir du code HTML. En transformant les < et > en &lt; et &gt; respectivement, elle désamorce les balises HTML qu'un visiteur aurait éventuellement saisies, ce qui évite par exemple qu'une balise <script> ou une <iframe> se retrouve affichée sur ton site à ton insu. Car là il pourrait se passer n'importe quoi. C'est le cas le plus évident d'attaque XSS.

    Pour l'anecdote, c'est arrivé sur Youtube en 2010. Il y avait une faille dans les commentaires qui faisait que si on écrivait deux balises <script> à la suite, la deuxième n'était pas retirée. La communauté de Reddit a réussi à défigurer une page de vidéo de Justin Bieber grâce à ça

    >> Dans le html, pour le message d'accueil 'Bonjour vinz', htmlentities est une bonne idée ?
    Elle n'est peut-être pas nécessaire, mais ça ne coûte presque rien de prendre la précaution. Ça va juste coûter un peu de temps de processeur sur le serveur.

    Quoi qu'il en soit, il vaut mieux contrôler les données au moment où elles sont envoyées. Par exemple, au moment où un nouvel utilisateur s'enregistre, tu vérifies que le pseudo ne contient pas de code HTML. De manière générale, il faut essayer d'avoir des données « propres » le plus tôt possible. En suivant cette logique, tu peux faire confiance à tes variables de session ($_SESSION['...']) car elles viennent de ton serveur et, en principe, elles sont déjà nettoyées.

    Pour résumer :
    • htmlentities : on s'en fout car normalement tu as réglé ton encodage partout.
    • Par contre htmlspecialchars est utile pour des données fraîches venant de l'utilisateur.
    • Tes variables de session sont censées être toujours propres. Donc pas besoin de htmlentities dessus. Mais le mettre par précaution ne coûte pas grand chose.
    • Contrôle toujours ce qui arrive au serveur, car il est facile de modifier/fabriquer une requête HTTP.

  14. #14
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2014
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 24
    Points : 8
    Points
    8
    Par défaut
    Merci bcp encore, ça répond à pas mal de questions que je me posais sur la sécurité... Il ne suffit pas de sécuriser le moment où on accède à la bdd, il faut aussi vérifier ce qu'on y insère. ça paraît évident quand on y pense, mais justement on y pense pas forcément


    * Pour l'inscription des clients, j'ai un form (input, submit etc.) et un traitement en php qui enregistre en bdd (mysql - classique)
    Le mieux est d'encoder avec htmlspecialchars avant POST vers php (dans ce cas, j'imagine qu'il faut faire une petite fonction : onSubmit(encode avec htmlspecialchars) - ou - dans la page php elle-même? (dans ce cas, on peut faire $id = (int) $_POST['id']; pour les nombres et PDO::quote() pour les string, c'est ça? )


    * A ce propos, au moment d'exécuter une requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $req->bindParam(':id', $id, PDO::PARAM_STR);
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $req->bindParam(':id', $id, PDO::PARAM_INT);
    fonctionnent tous les 2. C'est parce que la base mysql enregistre tout en string?


    * Pour la différence JS/PHP, je connais la base JS/client PHP/serveur, mais c'est vrai qu'on ne pense pas forcément à la distance entre les 2 quand on est en local! J'imagine qu'un bon code est celui qui tente de réduire les allers-retours entre html/js et php.
    Par exemple, j'ai une fonction de rajout de marqueur qui allait chercher le maxMarkerId en php à chaque fois (ensuite ds la focntion on fait ++ en JS pour enregistrer le nouveau marqueur avec un ID supérieur de 1 au max, pour incrémenter l'affaire). Et bien ça ne marchait bien que pour le premier ajout de marqueur.
    En déclarant maxMarkerId une fois pour toutes (tjs en php, mais en dehors de la fonction - en début de JS) et en faisant juste ++ (en JS) dans la focntion, plus de soucis.
    Tu crois que c'est justement ce problème de 'non synchronisation' entre JS et PHP? Du style, le php n'a pas le temps de renvoyer la bonne variable que le JS a déjà fini sa tournée ??


    * Et pour l'encodage, je fais tout avec notepad++ en utf8 sans bom et ai mis <meta charset=utf-8 /> en début de html. ça j'ai commencé à saisir avec le temps que sans utf8, c'était bien difficile notre belle langue pleine d'accents Je n'ai pas trop de problèmes (ou alors c'est résolu) pour l'instant de ce côté là.
    Sauf 2 petits trucs pas très graves :
    **je n'ai donc pas encore fait de htmlspecialchars ou autre sur les input pour vérifier l'absence de balises etc...
    A l'inscription, à la connexion et à l'entrée dans la bdd, le pseudo circule librement Or, si un pseudo Vinz est bien enregistré en base, on peut se connecter avec vinz ou Vinz indifféremment !
    **A la lecture sur phpMyAdmin, un peudo Rémi sera affiché Rémi. Pas de pb à la connexion ni si on affiche le contenu de la base via une page php utf8, mais bon... ça doit être une option à trouver dans phpMyAdmin.


    En tous cas, merci, et si tu en marre de répondre pas de soucis !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [2.x] Retrouver l'objet User dans un form de FosUserBundle
    Par DanaKil dans le forum Symfony
    Réponses: 0
    Dernier message: 18/05/2015, 13h30
  2. Agir sur des objets placés dans un tableau
    Par CyrilD dans le forum Général VBA
    Réponses: 2
    Dernier message: 27/03/2011, 22h06
  3. Retrouver l'index d'un(e) Item cliqué dans un ListBox
    Par Claude_Azoulai dans le forum VB.NET
    Réponses: 2
    Dernier message: 01/02/2010, 12h10
  4. [Vb.net] Indexé un objet crée dans une boucle
    Par picpic dans le forum Windows Forms
    Réponses: 10
    Dernier message: 17/12/2003, 14h37
  5. Réponses: 3
    Dernier message: 09/02/2003, 01h09

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo