[RESOLU] Affichage listes déroulantes liées

[Compte supprime]
Invité n'ayant pas de compte PHPfrance

20 mars 2013, 14:44

Bonjour,

J'ai en interne développé un ptit site pour la gestion de notre réseau. Il s'agit surtout de gérer les adresses ip de notre parc. Les adresses IP sont liées à un réseau, j'ai donc adapté un bout de code que j'ai trouvé sur ce forum (merci Cyrano!) pour la gestion des listes déroulantes liées. L'exemple utilisé à la base est Région/Département que j'ai adapté pour Réseau/AdresseIP.

Je mets seulement les parties intéressantes au problème :
$query_reseau = $bdd->query("SELECT adresse_ip AS idd, RESEAUX.id_reseau AS idr, RESEAUX.nom_reseau AS inr FROM IP, RESEAUX WHERE IP.id_reseau = RESEAUX.id_reseau AND adresse_ip NOT IN (SELECT adresse_ip FROM IP_MAT) ORDER BY RESEAUX.id_reseau, INET_ATON(adresse_ip)");
 
            /* Pour ne pas écraser mes tableaux, je crée un témoin */
            $temoin_r = 0;
            /* Création du tableau PHP des valeurs récupérées */
            $reseaux = array();
            /* Index de l'adresse ip par tableau réseau */
            $id = 0;
            while ($ligne = $query_reseau->fetch()) {
                $r = $ligne['idr'];
                $d = $ligne['idd'];
                /* Je vérifie si je suis toujours dans le même réseau, sinon je crée les tableaux nécessaires */
                if ($temoin_r != $r) {
                    $reseaux[$r] = array();
                    /* J'ajoute le réseau */
                    $reseaux[$r][0] = $ligne['idr'];
                    $reseaux[$r][1] = array();
                    $reseaux[$r][2] = array();
                    $temoin_r = $r;
                    $id = 0;
                }
                /* J'ajoute les ips */
                $reseaux[$r][1][$id] = $d;
                $reseaux[$r][2][$id] = $ligne['idd'];
                $id++;
            }
            /* On sérialise le tableau obtenu pour traitement par JavaScript */
            $chaine = htmlspecialchars(serialize($reseaux), ENT_QUOTES);
            ?>
            <script type="text/javascript">
                /* <![CDATA[ */
                <!--
                /*
                 * Ici, on transmets la chaîne sérialisée à JavaScript pour la transformer en tableau indexé JavaScript
                 */
                var tableau = new PhpArray2Js('<?php echo $chaine; ?>');
                var tab = tableau.retour();
                // -->
                /* ]]> */
            </script>
Ensuite, la partie affichage :
<select name="edit_reseau" style="text-align:center;" id="reseau" onchange="changeIP(tab,this.value);">
                                        <option value="vide">- - - Sélectionnez le réseau - - -</option>
                                        <?php
                                        /* Construction de la première liste : on se sert du tableau PHP */
                                        $nbr = count($reseaux);
                                        foreach ($reseaux as $nr => $nom) {
                                            ?>
                                            <option style="text-align:center;" value="<?php echo($nr); ?>"><?php echo($nom[0]); ?></option>
                                            <?php
                                        }
                                        ?>
                                    </select><br><tr><td class="td_modif_mini">Adresse IP</td><td><br>                                    <span style="text-align:center;" id="blocIP"></span><input type="hidden" name="recup_ip" id="recup_ip"/></td></tr>
Pour la partie AdresseIP, il y a un script JS qui renvoi bien la bonne IP.


Ce script dans son état actuelle fonctionne sans souci. Le problème, c'est qu'il m'affiche l'ID du réseau et pas son nom... Du coup, je dois afficher un petit tableau en dessous pour sélectionner le bon réseau. (ex: numéro 15 pour Réseau Imprimantes, dur de se souvenir de tous les numéros.. :-)).

Petite question supplémentaire, à force de modifier, d'adapter, etc... la ligne :
$nbr = count($reseaux);<br><br>
On est d'accord, elle ne sert à rien ??

Merci pour votre aide.

Mammouth du PHP | 19672 Messages

20 mars 2013, 16:00

Salut,
pour la ligne inutile de comptage, je confirme, elle ne sert à rien par rapport au code montré.

Pour l'identifiant au lieu du nom, il faudrait qu'on voie la structure du tableau de données, un var_dump serait utile pour ça :partant de là, on identifie quel index doit être utilisé pour afficher la bonne donnée.

Ceci dit, le MP n'était pas utile, presque n'importe qui ici aurait pu répondre la même chose ;)
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

[Compte supprime]
Invité n'ayant pas de compte PHPfrance

20 mars 2013, 16:13

Le var_dump() sur la variable $ligne me renvoi l'intégralité du tableau avec des adresses IP avec le numéro + nom du réseau, exemple de la 1ère ligne, ça donne :

Code : Tout sélectionner

array(6) { ["idd"]=> string(10) "192.168.0.1" [0]=> string(10) "192.168.0.1" ["idr"]=> string(1) "1" [1]=> string(1) "1" ["inr"]=> string(6) "Test" [2]=> string(6) "Test" }
Désolé pour le MP.

Mammouth du PHP | 19672 Messages

20 mars 2013, 16:18

OK,
donc au lieu d'utiliser $ligne[idr] ou $ligne[1], il faut utiliser $ligne[inr] ou $ligne[2] si tu veux afficher le nom du réseau au lieu de son identifiant.
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

[Compte supprime]
Invité n'ayant pas de compte PHPfrance

20 mars 2013, 16:25

J'avais déjà testé cette possibilité, on est d'accord, j'en ai seulement 2 à modifier ?

Du coup, je viens de retenter, j'ai modifié les 2 "$ligne['idr']' par "$ligne['inr']" et dans la liste déroulante, ça me renvoi :

Code : Tout sélectionner

Notice: Undefined offset: 0 in /var/www/test/modification/modif_materiels/modif_select_ip.php on line 104
Pour info, la ligne 104 dans mon code c'est :
<option style="text-align:center;" value="<?php echo($nr); ?>"><?php echo($nom[0]); ?></option>
                                            

Mammouth du PHP | 19672 Messages

20 mars 2013, 16:31

Erreur classique de tableau mal maitrisé.

Dans pareil cas, il est vain de jouer aux devinettes, on inspecte ce que contient la variable indiquée. Ici, $nom[0] ne semble pas exister, donc, la question à se poser, c'est « Qu'est-ce que contient cette variable ? », donc sur la ligne précédente, tu insères ceci :
echo("<pre>\n");
var_dump($nom);
echo("</pre>\n");
Et là tu verras ta réponse pour corriger.
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

[Compte supprime]
Invité n'ayant pas de compte PHPfrance

20 mars 2013, 16:39

Le tableau ne renvoi que les adresses ip et un numéro de réseau, je n'ai pas le nom qui apparaît, ça donne :

Code : Tout sélectionner

array(2) { [1]=> array(254) { [0]=> string(11) "192.168.0.1"
etc...

Le problème vient donc de array(2) et du [1] =>, il est reprit pour tous les réseaux, il n'est jamais différent... Du coup, la boucle forearch ne reçoit pas le nom du réseau

Mammouth du PHP | 19672 Messages

20 mars 2013, 17:08

Donc... le problème est en amont, tu ne crois pas ? :-*
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

[Compte supprime]
Invité n'ayant pas de compte PHPfrance

20 mars 2013, 17:12

C'est dans cette partie ?

Code : Tout sélectionner

$reseaux[$r][0] = $ligne['inr']; $reseaux[$r][1] = array(); $reseaux[$r][2] = array();
Le var_dump($nom) renvoi toujours [1] => Array ou [2] => Array.

On est d'accord, à la place de "Array", je devrais avoir le nom du réseau ?

La variable $r reçoit bien les bonnes informations !

Du coup, je valide, l'erreur est dans ma sélection du haut !

Mammouth du PHP | 19672 Messages

20 mars 2013, 17:39

Mouais, je sens que ça va être laborieux...

Lorsque tu te heurtes à un dysfonctionnement inattendu dans l'exécution d'un code, il faut cerner le problème. Il est donc important au préalable de l'identifier.
Donc reprenons : le problème est qu'au lieu du nom du réseau, tu fais afficher son identifiant. Partant de là, la logique la plus élémentaire indique qu'il y a une erreur dans la construction du tableau de données.

Partons alors du tableau de données retourné par ta requête SQL. Si je ne fais pas erreur, il doit ressembler à quelque chose dans ce style :

Code : Tout sélectionner

array(2) { array(6) { ["idd"] => string(10) "192.168.0.1" [0] => string(10) "192.168.0.1" ["idr"] => string(1) "1" [1] => string(1) "1" ["inr"] => string(6) "Test" [2] => string(6) "Test" }, array(6) { ["idd"] => string(10) "192.168.0.2" [0] => string(10) "192.168.0.2" ["idr"] => string(1) "2" [1] => string(1) "2" ["inr"] => string(6) "Test_2" [2] => string(6) "Test_2" } }
On a là un tableau de tableaux. Pour chacun des sous-tableaux, lesquels correspondent aux lignes retournées par ta base de données, ce qui nous intéresse, ce sont les adresses IP et les noms des réseaux.

Regarde maintenant le code de ta boucle while : tu y construis un tableau $reseaux. Je ne suis pas certain de bien saisir ce que tu essayes d'obtenir en sortie, mais la question à te poser est la suivante : est-ce qu'à la sortie de la boucle while ton tableau $reseaux contient bien ce que tu veux ? Pour le vérifier, c'est facile, juste après la fermeture de la boucle while, tu ajoutes un
echo("<pre>\n");
var_dump($reseaux);
echo("</pre>\n");
Tu y verras la structure dont tu dois te servir ensuite pour construire les éléments affichés et surtout les bons indexes à utiliser pour afficher les données appropriées.

Est-ce que ça colle jusque là ? Et normalement, tu n'a nulle part de nom de réseau : normal, nulle part dans la boucle while tu n'utilises $ligne['inr'] ni $ligne[2].

CQFD ...
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

[Compte supprime]
Invité n'ayant pas de compte PHPfrance

20 mars 2013, 18:02

Quand je lance le
echo("<pre>\n");
var_dump($reseaux);
echo("</pre>\n");
J'ai bien le nom du réseau qui apparaît, exemple :

Code : Tout sélectionner

["Supervision"]=> array(2) { [1]=> array(254) { [3044]=> string(12) "192.168.10.1" [3045]=>
Par contre, certains apparaissent en double sans nom.

Mais dans la boucle while :
while ($ligne = $query_reseau->fetch()) {
                $r = $ligne['inr'];
                $d = $ligne['idd'];
                /* Je vérifie si je suis toujours dans le même réseau, sinon je crée les tableaux nécessaires */
                if ($temoin_r != $r) {
                    $reseaux[$r] = array();
                    /* J'ajoute le réseau */
                    $reseaux[$r][0] = $ligne['inr'];                    
                    $reseaux[$r][1] = array();
                    $reseaux[$r][2] = array();
                    $temoin_r = $r;
                    $id = 0;
                }
                /* J'ajoute les ips */
                $reseaux[$r][1][$id] = $d;
                $reseaux[$r][2][$id] = $ligne['idd'];
                $id++;
            }
J'utilise bien $ligne['inr'] 2 fois. Pour la question ce que j'essaie d'obtenir, c'est exactement la même chose que Région/Département mais avec un Réseau et des Adresses IP.

Mammouth du PHP | 19672 Messages

20 mars 2013, 18:14

Ben tu ne l'utilisais pas dans le premier code que tu as montré.

Ensuite, tu montre un var_dump partiel, j'ai un peu de mal à comprendre où tu coinces parce que maintenant, tu disposes à priori des bonnes données. :-k
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

[Compte supprime]
Invité n'ayant pas de compte PHPfrance

20 mars 2013, 18:17

Oui dans le premier, c'était le code initiale que j'ai modifié après ton aide pour remplacer IDR par INR.

En fait, je suis toujours offset pour nom[0] dans la liste déroulante, si je mets [1], j'ai des Array partout.

Je remets une partie du var_dump, il est très long, au milieu, le réseau Test est en double et sans nom :

Code : Tout sélectionner

array(24) { ["Test"]=> array(2) { [1]=> array(254) { [0]=> string(10) "172.30.0.1" [1]=> string(10) "172.30.0.2" [2]=> string(10) "172.30.0.3" [3]=> string(10) "172.30.0.4" [4]=> string(10) "172.30.0.5" [...] [253]=> string(12) "172.30.0.254" } [2]=> array(254) { [0]=> string(10) "172.30.0.1" [1]=> string(10) "172.30.0.2" [2]=> string(10) "172.30.0.3" [3]=> string(10) "172.30.0.4" [4]=> string(10) "172.30.0.5" [5]=> string(10) "172.30.0.6" [...] string(12) "172.30.0.253" [253]=> string(12) "172.30.0.254" } } ["Test2"]=> array(2) { [1]=> array(254) { [254]=> string(11) "192.168.2.1" [255]=> string(11) "192.168.2.2"

Mammouth du PHP | 19672 Messages

20 mars 2013, 18:20

Oui, parce que $nom[0] contient des tableaux et non des valeurs scalaires, donc un echo affiche « Array » : il manque un index et donc ça veut dire que tu devrais afficher $nom[0][nom-de-l-index-manquant].
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

[Compte supprime]
Invité n'ayant pas de compte PHPfrance

20 mars 2013, 18:23

Je crois que je suis perdu au 12ème sous-sous-sous tableau ! |*()

Ce que je comprends pas, c'est que si je remets IDR au lieu de INR, il a aucun souci, il me ressort le numéro de réseau sans problème...