Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Boucle foreach imbriqué & Array

1 réponse
Avatar
Yoann
Bonjour,

J'ai actuellement un script qui me permet de faire du monitoring sur mes
serveurs via les modules Net::Ping, et Net::Telnet.

Toutes les informations sur les différents serveur sont stocké dans une
base Mysql dans 3 tables (Il y a une interface en PHP pour faire les
changements) :
- servers
- interfaces
- services

Tout cela fonctionne très bien sauf qu'actuellement le script perl, fait
un nombre de requete SQL important.
(server * nb interface * nb services/interface) * nb server = BCP trop !!

Ce que je voudrais donc faire, c'est ce que je fait sur l'interface
d'administration en PHP, c-a-d stocker le resultat de ma requete dans un
tableau, et via des boucles foreach pouvoir regénérer l'arborescence et
effectué les tests (ping puis telnet):
# Server 1
> Interface 1
>> Service 1
>> Service 2
> Interface 2
>> Service 1
>> Service 2
# Server 2
.. etc ..


Je génére donc un tableau assez complexe lors de l'excecution de la
requete SQL :

$query = "...";
$sth = $dbh->prepare($query);
$res = $sth->execute;
my %SERVEUR=();
while ($inter = $sth->fetchrow_hashref)
{
%SERVEUR->{$inter->{server_id}}{'server_name'}=$inter->{server_name};
%SERVEUR->{$inter->{server_id}}{'server_description'}=$inter->{server_description};
%SERVEUR->{$inter->{server_id}}{'server_alerte'}=$inter->{server_alerte};

%SERVEUR->{$inter->{server_id}}{'dev'}{$inter->{interface_id}}{'interface_name'}=$inter->{interface_name};
%SERVEUR->{$inter->{server_id}}{'dev'}{$inter->{interface_id}}{'interface_description'}=$inter->{interface_description};
%SERVEUR->{$inter->{server_id}}{'dev'}{$inter->{interface_id}}{'interface_host'}=$inter->{interface_host};
%SERVEUR->{$inter->{server_id}}{'dev'}{$inter->{interface_id}}{'interface_ip'}=$inter->{interface_ip};
%SERVEUR->{$inter->{server_id}}{'dev'}{$inter->{interface_id}}{'interface_alerte'}=$inter->{interface_alerte};
%SERVEUR->{$inter->{server_id}}{'dev'}{$inter->{interface_id}}{'interface_ping'}=$inter->{interface_ping};
%SERVEUR->{$inter->{server_id}}{'dev'}{$inter->{interface_id}}{'interface_last_ping'}=$inter->{interface_last_ping};
%SERVEUR->{$inter->{server_id}}{'dev'}{$inter->{interface_id}}{'service'}{$inter->{service_id}}{'service_name'}=$inter->{service_name};
%SERVEUR->{$inter->{server_id}}{'dev'}{$inter->{interface_id}}{'service'}{$inter->{service_id}}{'service_description'}=$inter->{service_description};
%SERVEUR->{$inter->{server_id}}{'dev'}{$inter->{interface_id}}{'service'}{$inter->{service_id}}{'service_port'}=$inter->{service_port};
%SERVEUR->{$inter->{server_id}}{'dev'}{$inter->{interface_id}}{'service'}{$inter->{service_id}}{'service_alerte'}=$inter->{service_alerte};
%SERVEUR->{$inter->{server_id}}{'dev'}{$inter->{interface_id}}{'service'}{$inter->{service_id}}{'service_last_check'}=$inter->{service_last_check};
}

Jusque la aucun soucis.

La ou ca se complique c'est sur les boucles foreach imbriqués.
Le 1er foreach fonctionne tres bien et m'affiche la liste des serveurs.
Le 2eme lui ne fonctionne pas du tout et devrais me renvoyer la liste
des interfaces du serveur.
(J'ai pas intégré le 3eme foreach pour la boucle sur les
services/interfaces/servers ..)

@ListKeysServeur = keys(%SERVEUR);
foreach $KeyServeur (@ListKeysServeur) {
print " # ".$SERVEUR{$KeyServeur}{'server_name'}." -
".$SERVEUR{$KeyServeur}{'server_description'}."\n";

%INTERFACE = $SERVEUR{$KeyServeur}{'dev'};
@ListKeysInterface = keys(%INTERFACE);
foreach $KeyInterface (@ListKeysInterface) {
print " > ".$INTERFACE{$KeyInterface}{'interface_name'}." -
".$INTERFACE{$KeyInterface}{'interface_description'}."\n";
}

}


J'ai passé la nuit dessus, sans arrivé a rien.
Cette methode fonctionne tres bien dans un script PHP, mais n'etant pas
un PRO de Perl, cela n'est peut etre pas possible ..

Voila ce qui marche en PHP :

foreach($SERVEUR AS $s_id => $Vserveur)
{
echo "# ".$Vserveur['name']."<br>\n";
foreach($Vserveur['dev'] AS $i_id => $Vinterface)
{
echo ">> ".$Vinterface['name']."<br>\n";
foreach($Vinterface['service'] AS $p_id => $Vservice)
{
echo ">>> ".$Vservice['name']."<br>\n";
}
}
}


Grand merci par avance ..

Yoann

1 réponse

Avatar
Yoann
La ou ca se complique c'est sur les boucles foreach imbriqués.
Le 1er foreach fonctionne tres bien et m'affiche la liste des serveurs.
Le 2eme lui ne fonctionne pas du tout et devrais me renvoyer la liste
des interfaces du serveur.


Je me repond à moi meme :

Le probleme venait en faite de la ligne :
%INTERFACE = $SERVEUR{$KeyServeur}{'dev'};

Il faut en faite déréférencer la valeur pour accéder au hash :
my %INTERFACE = %{$SERVEUR{$KeyServeur}{'dev'}};

Et Hop voila ca marche.

Merci au salon #perl sur irc.epiknet.org
--
Yoann