Lecture d'un fichier de définitions (genre INI)

Résolu/Fermé
heliconius Messages postés 545 Date d'inscription mardi 1 juillet 2008 Statut Membre Dernière intervention 23 juin 2023 - 25 janv. 2021 à 18:07
heliconius Messages postés 545 Date d'inscription mardi 1 juillet 2008 Statut Membre Dernière intervention 23 juin 2023 - 26 janv. 2021 à 15:48
Bonjour tout le monde,

Soit le petit réseau local d'une famille de plusieurs personnes (voire, pourquoi pas, d'une petite entreprise), chacune de celles-ci pouvant avoir PC fixe, PC portable, tablette, smartphone et prévision d'accès Internet aux invités.

Je réalise un script PHP pour automatiser l'écriture des fichiers nécessaires à des serveurs GNU/Linux : un serveur DNS local ainsi qu'un serveur DHCP pour ce réseau local qui comprend une partie privée (192.168.0.0) et une DMZ (192.168.10.0).

Le script (mkfiles.php) lit un fichier de définition ("lan.txt" = genre fichier INI adapté) comme ci-dessous :
(NB: les lignes vides ou débutant par # ou par ; sont ignorées)

# Lan définition
# Domaine des papillons (parpaioun.net)
# Mis en place le JJ/MM/AAAA

[lan]
network=192.168.0
mask=255.255.255.0
domain=parpaioun.net
dhcpd=vulcain
lease=43200
maxlease=86400
dns1=vulcain.parpaioun.net
dns2=80.10.246.3

[snet1]
net=192.168.0.0
mask=255.255.255.0
range=192.168.0.2 192.168.0.35
bcast=192.168.0.255
router=192.168.0.1
hosts=lasn1

[snet2]
net=192.168.10.0
mask=255.255.255.0
range=192.168.10.226 192.168.10.230
bcast=192.168.10.255
hosts=lasn2

[lasn1]
# hostname;mac@;ip;role / Réseau local privé
netgear;00:0F:B5:B1:B0:28;192.168.0.1;Routeur/Passerelle
srv-2;00:00:00:00:00:02;192.168.0.2;Réservé service
// NB: ... etc ...
morpho;C0:FF:D4:B0:B8:C6;192.168.0.8;Hotspot WIFI
vulcain;00:60:97:A6:FF:89;192.168.0.9;Serveur FTP/Web local
samia;00:01:E6:35:B7:49;192.168.0.10;Imprimante réseau
kallima;B0:6E:BF:2F:CF:B4;192.168.0.11;PC fixe MC
zigzag;98:3B:16:18:94:D5;192.168.0.12;Tablette MC
hepialus;3C:CD:5D:83:E0:BC;192.168.0.13;Huawei P30 MC
lysandra;3C:CD:5D:83:E0:BC;192.168.0.14;Portable MC
// NB: ... 192.168.0.11 à 20 : réservé MC ...
cypris;00:E0:4C:39:4C:4D;192.168.0.21;PC fixe Pierre
// NB: ... 192.168.0.21 à 30 : Réservé Pierre ...
guest-31;;192.168.0.31;Invité
// NB: ... 192.168.0.31 à 35 : Invités ...
guest-35;;192.168.0.35;Invité

[lasn2]
# hostname;mac@;ip;role / DMZ du réseau local
monarque;01:02:03:04:05:06;192.168.10.226;Serveur Web
rethenor;B8:27:EB:85:20:13;192.168.10.227;Serveur FTP
// NB: ... 192.168.10.228 à 192.168.10.230 : réservé services ...

# Fin de fichier

Dans lequel "snet" signifie "subnet" et il pourrait n'y en avoir qu'un ou deux ou trois (rubriques snet1, snet2, etc...) selon la configuration choisie pour le réseau local et dans lesquels le "hosts" des rubriques "snet?" pointe vers une rubrique (lasn1, lasn2, etc. --local area subnet--) contenant la liste des hôtes de ce sous-réseau.

Lors de la lecture du fichier de définition, je bute sur la partie "snet?". J'aimerais lire ce fichier et faire des tableaux de chaque rubrique [ rubrique "lan" => $lan = array() ] mais quelque soit le nombre de "snet?", faire qu'il n'y ait qu'un seul tableau "$snet" contenant autant de sous-tableaux "$snet[?]" qu'il n'y a de sous-réseaux. Un seul tableau "$snet" me permettrait de compter le nombre de sous-réseaux avec un count($snet). J'aimerais que le résultat soit le suivant :

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
print_r($lan); // Réseau local (domaine)
Array
(
    [0] => network=192.168.0
    [1] => mask=255.255.255.0
    [2] => domain=parpaioun.net
    [3] => dhcpd=vulcain
    [4] => lease=43200
    [5] => maxlease=86400
    [6] => dns1=vulcain.parpaioun.net
    [7] => dns2=80.10.246.3
)

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
print_r($snet); // subnets
Array
(
    [0] => Array
        (
            [0] => net=192.168.0.0
            [1] => mask=255.255.255.0
            [2] => range=192.168.0.2 192.168.0.35
            [3] => bcast=192.168.0.255
            [4] => router=192.168.0.1
            [5] => hosts=lasn1
        )
    [1] => Array
        (
            [0] => net=192.168.10.0
            [1] => mask=255.255.255.0
            [2] => range192.168.10.226 192.168.10.230
            [3] => bcast=192.168.10.255
            [4] => router=192.168.10.254
            [5] => hosts=lasn2
        )
)

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
print_r($lasn1);
Array
(
    [0] => # hostname;mac@;ip;role - Réseau local privé
    [1] => netgear;00:0F:B5:B1:B0:28;192.168.0.1;Routeur/Passerelle
    [2] => srv-2;00:00:00:00:00:02;192.168.0.2;Réservé service
    [3] => ... etc ...
    [8] => morpho;C0:FF:D4:B0:B8:C6;192.168.0.8;Hotspot WIFI
    [9] => vulcain;00:60:97:A6:FF:89;192.168.0.9;Serveur FTP/Web local
    [10] => samia;00:01:E6:35:B7:49;192.168.0.10;Imprimante réseau
    [11] => Kallima;B0:6E:BF:2F:CF:B4;192.168.0.11;PC fixe MC
    [12] => zigzag;98:3B:16:18:94:D5;192.168.0.12;Tablette MC
    [13] => hepialus;3C:CD:5D:83:E0:BC;192.168.0.13;Huawei P30 MC
    [14] => lysandra;3C:CD:5D:83:E0:BC;192.168.0.14;Portable MC
    [15] => ... 192.168.0.15 à 20 : réservé MC ...
    [21] => cypris;00:E0:4C:39:4C:4D;192.168.0.21;PC fixe Pierre
    [22] => ... 192.168.0.21 à 30 : Réservé Pierre ...
    [31] => guest-31;;192.168.0.31;Invité
    [32] => ... 192.168.0.31 à 35;Invités ...
    [33] => guest-35;;192.168.0.35;Invité
)

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
print_r($lasn2);
Array
(
    [0] => # hostname;mac@;ip;role - DMZ du réseau local
    [1] => monarque;01:02:03:04:05:06;192.168.10.226;Serveur Web
    [2] => rethenor;B8:27:EB:85:20:13;192.168.10.227;Serveur FTP
    [3] => ... 192.168.10.228 à 192.168.10.230 : réservé services ...
)

Ce résultat obtenu, la création des fichiers dhcpd.conf, named.boot et autres fichiers du DNS ne pose pas de problème.

Voici mon code (erreur comprise) :

<?php
// file: mkfile.php (19/01/2021)

$inputfile = "lan.txt";

$hf = fopen($inputfile, "r");

function iscomment($line) {
	if(strlen($line) == 0) { return true; }
	if($line[0] == "#" || $line[0] == ";") { return true; } else { return false; }
}

// Lecture définitions
while(!feof($hf)) {
	$line = trim(fgets($hf,1024));
	if(!iscomment($line)) {
		if(eregi("^\[lan\]$",$line)) {
			$rubrique = substr($line,1,-1);
			$$rubrique = array();
			$line = trim(fgets($hf,1024));
		}

		if(eregi("^\[snet[1-9]{1}\]$",$line)) {
			$rubrique = substr($line,1,-1);
			$num = substr($line,5,1)-1;
			$$rubrique[$num] = array();
			$line = trim(fgets($hf,1024));
		}

		if(eregi("^\[lasn[1-9]{1}\]$",$line)) {
			$rubrique = substr($line,1,-1);
			$$rubrique = array();
			$line = trim(fgets($hf,1024));
		}
		${$rubrique}[] = $line;
	}
}

fclose($hf);
print_r($lan);   // OK
print_r($snet);  // msg: Undefined variable: snet in /root/work/lan/mkfiles.php on line 40 
print_r($lasn1); // OK
print_r($lasn2); // OK
?>

Voilà je ne sais depuis combien de temps je bloque sur la réalisation d'un seul tableau $snet pour toutes les caractéristiques des différents sous-réseaux (les définitions de ceux-ci formant des "sous-tableaux").

Quelqu'un aurait-il une idée ? Merci.

Configuration: Windows / Firefox 52.0

A voir également:

2 réponses

yg_be Messages postés 22920 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 4 juillet 2024 1 481
25 janv. 2021 à 18:59
bonjour,
pendant que tu étais bloqué, as-tu pris le temps d'observer la valeur de $rubrique après la ligne 24? je pense que cela te permettra de corriger la ligne 24 et d'obtenir le résultat attendu?

en ligne 26, pourquoi n'utilises-tu pas
$snet
au lieu de
$$rubrique
?
0
heliconius Messages postés 545 Date d'inscription mardi 1 juillet 2008 Statut Membre Dernière intervention 23 juin 2023 139
25 janv. 2021 à 19:16
Depuis prèsque une semaine que je suis sur le problème, tu penses bien que j'ai testé la valeur de $rubrique (=> snet) après la ligne 25 ainsi que $$rubrique[$num] ($snet[0] ou $snet[1]) après la ligne 27 ! Et c'est bon.

Pourquoi je n'utilise pas $snet au lieu de $$rubrique en ligne 27 ? Parce que la ligne 36 qui ajoute la valeur lue utilise $rubrique ( $[$rubrique}[] = $ligne; ) et non $snet. Le principe est bon pour les tableaux à 1 niveau (voir $lan, $lasn1 et $lasn2). le tableau se remplit par la ligne 36. Le problème est les sous-tableaux à la place des lignes...
0
yg_be Messages postés 22920 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 4 juillet 2024 1 481 > heliconius Messages postés 545 Date d'inscription mardi 1 juillet 2008 Statut Membre Dernière intervention 23 juin 2023
Modifié le 25 janv. 2021 à 19:59
ton soucis, c'est bien
Undefined variable: snet
en ligne 41?

je me demande comment il se fait que, quand tu exécutes
$rubrique = substr($line,1,-1);

et que $line contient [snet1],
tu obtiens snet dans $rubrique
0
yg_be Messages postés 22920 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 4 juillet 2024 1 481
25 janv. 2021 à 19:58
moi, je ferais ainsi: après la ligne 27, je consommerais toutes les lignes jusqu'à la rubrique suivante.

par ailleurs, si tu persistes dans l'idée de variable dynamique, il me semble indispensable que ta ligne 26 soit identique à ta ligne 19. sinon comment ta ligne 35 peut-elle fonctionner?
ceci me semble donc plus correct (non testé):
if(eregi("^\[snet[1-9]{1}\]$",$line)) {
			$num = substr($line,5,1)-1;
            $rubrique = "snet[".$num."]";
			$$rubrique = array();
			$line = trim(fgets($hf,1024));
		}
0
yg_be Messages postés 22920 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 4 juillet 2024 1 481
25 janv. 2021 à 20:44
plutôt:
if(eregi("^\[snet[1-9]{1}\]$",$line)) {
			$num = substr($line,5,1)-1;
            $snet[$num] = array();
			$rubrique =& $snet[$num];
			$line = trim(fgets($hf,1024));
		}

et, en ligne 36, utiliser $rubrique, pas $$rubrique;
0
yg_be Messages postés 22920 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 4 juillet 2024 1 481 > yg_be Messages postés 22920 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 4 juillet 2024
25 janv. 2021 à 20:48
il faudra bien sûr faire de même partout:
	if(!iscomment($line)) {
		if(eregi("^\[lan\]$",$line)) {
			$lan = array();
            $rubrique =& $lan;
			$line = trim(fgets($hf,1024));
		}
0
heliconius Messages postés 545 Date d'inscription mardi 1 juillet 2008 Statut Membre Dernière intervention 23 juin 2023 139 > yg_be Messages postés 22920 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 4 juillet 2024
26 janv. 2021 à 01:03
J'ai essayé avec :
		if(eregi("^\[snet[1-9]{1}\]$",$line)) {
			$num = substr($line,5,1)-1;
			$rubrique = "snet[".$num."]";
			echo "===: $rubrique\n";
			$$rubrique = array();
			$line = trim(fgets($hf,1024));
		}

et
		if(eregi("^\[snet[1-9]{1}\]$",$line)) {
			$num = substr($line,5,1)-1;
			$snet[$num] = array();
			$rubrique =& $snet[$num];
			$line = trim(fgets($hf,1024));
		}

1) sans toucher à la ligne 36 :
=> écriture de ===: snet[0] et ===: snet[1]
=> la tableau $snet : variable snet non définie
=> les tableaux $lan, $lasn1 et $lasn2 étaient corrects
2) en remplaçant $$rubrique par $rubrique en ligne 36 :
=> même résultat.
3) en homogénéisant pour les rubriques lan, lasn1 et lsan2 :
=> plus rien ne fonctionne.

Vraie prise de tête...
0
yg_be Messages postés 22920 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 4 juillet 2024 1 481 > heliconius Messages postés 545 Date d'inscription mardi 1 juillet 2008 Statut Membre Dernière intervention 23 juin 2023
26 janv. 2021 à 11:26
il faut probablement ajouter en ligne 12:
$snet = array();  
0
heliconius Messages postés 545 Date d'inscription mardi 1 juillet 2008 Statut Membre Dernière intervention 23 juin 2023 139 > yg_be Messages postés 22920 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 4 juillet 2024
26 janv. 2021 à 15:48
Problème résolu.
Merci beaucoup pour ton aide. Voici les fichiers (définitions, script) et résultat. J'ai modifié le nom des rubriques pour que ce soit plus clair et modifié la composition des tableaux pour que ce soit plus homogène :
1 réseau local => 1 tableau
X sous-réseaux :
- => 1 tableau de X tableaux de sous-réseau
- => 1 tableau de X tableaux d'hôtes (par sous-réseau)

Fichier INI de définition :
# Lan définition
# Domaine des papillons (parpaioun.net)
# Mis en place le JJ/MM/AAAA

[lan]
network=192.168.0
mask=255.255.255.0
domain=parpaioun.net
dhcpd=vulcain
lease=43200
maxlease=86400
dns1=vulcain.parpaioun.net
dns2=80.10.246.3

[subnet1]
net=192.168.0.0
mask=255.255.255.0
range=192.168.0.2 192.168.0.35
bcast=192.168.0.255
router=192.168.0.1
lasn=lasn1

[subnet2]
net=192.168.10.0
mask=255.255.255.0
range=192.168.10.226 192.168.10.230
bcast=192.168.10.255
router=192.168.10.254
lasn=lasn2

[hosts1]
# hostname;mac@;ip;role - Réseau local privé
netgear;00:0F:B5:B1:B0:28;192.168.0.1;Routeur/Passerelle
srv-2;00:00:00:00:00:02;192.168.0.2;Réservé service
... etc ...
morpho;C0:FF:D4:B0:B8:C6;192.168.0.8;Hotspot WIFI
vulcain;00:60:97:A6:FF:89;192.168.0.9;Serveur FTP/Web local
samia;00:01:E6:35:B7:49;192.168.0.10;Imprimante réseau
Kallima;B0:6E:BF:2F:CF:B4;192.168.0.11;PC fixe MC
zigzag;98:3B:16:18:94:D5;192.168.0.12;Tablette MC
hepialus;00:00:00:00:00:13;192.168.0.13;Huawei P30 MC
ysandra;3C:CD:5D:83:E0:BC;192.168.0.14;Portable MC
... 192.168.0.15 à 20 : réservé MC ...
cypris;00:E0:4C:39:4C:4D;192.168.0.21;PC fixe Pierre
... 192.168.0.21 à 30 : Réservé Pierre ...
guest-31 à 35;;192.168.0.31 à 35;Invité

[hosts2]
# hostname;mac@;ip;role - DMZ du réseau local
monarque;01:02:03:04:05:06;192.168.10.226;Serveur Web
rethenor;B8:27:EB:85:20:13;192.168.10.227;Serveur FTP
... 192.168.10.228 à 192.168.10.230 : réservé services ...


Script de lecture du fichier de définition :
<?php
// file: mkfile.php (26/01/2021)

$inputfile = "lan.txt";

$hf = fopen($inputfile, "r");

function iscomment($line) {
        if(strlen($line) == 0) { return true; }
        if($line[0] == "#" || $line[0] == ";") { return true; } else { return false; }
}

// Lecture définitions
while(!feof($hf)) {
        $line = trim(fgets($hf,1024));
        if(!iscomment($line)) {

                if(eregi("^\[lan\]$",$line)) {
                        $rubrique = substr($line,1,-1);
                        $lan = array();
                        $rubrique =& $lan;
                        $line = trim(fgets($hf,1024));
                }

                if(eregi("^\[subnet[1-9]{1}\]$",$line)) {
                        $num = substr($line,7,1)-1;
                        $subnet[$num] = array();
                        $rubrique =& $subnet[$num];
                        $line = trim(fgets($hf,1024));
                }

                if(eregi("^\[hosts[1-9]{1}\]$",$line)) {
                        $num = substr($line,6,1)-1;
                        $hosts[$num] = array();
                        $rubrique =& $hosts[$num];;
                        $line = trim(fgets($hf,1024));
                }

                $rubrique[] = $line;
        }
}

fclose($hf);

print_r($lan);     // OK
print_r($subnet);  // OK
print_r($hosts);   // OK

// Avec les données des tableaux,
// écriture des fichiers du DNS et du DHCP

?>

Dump des tableaux :
Array
(
    [0] => network=192.168.0
    [1] => mask=255.255.255.0
    [2] => domain=parpaioun.net
    [3] => dhcpd=vulcain
    [4] => lease=43200
    [5] => maxlease=86400
    [6] => dns1=vulcain.parpaioun.net
    [7] => dns2=80.10.246.3
)
Array
(
    [0] => Array
        (
            [0] => net=192.168.0.0
            [1] => mask=255.255.255.0
            [2] => range=192.168.0.2 192.168.0.35
            [3] => bcast=192.168.0.255
            [4] => router=192.168.0.1
            [5] => lasn=lasn1
        )

    [1] => Array
        (
            [0] => net=192.168.10.0
            [1] => mask=255.255.255.0
            [2] => range=192.168.10.226 192.168.10.230
            [3] => bcast=192.168.10.255
            [4] => router=192.168.10.254
            [5] => lasn=lasn2
        )

)
Array
(
    [0] => Array
        (
            [0] => # hostname;mac@;ip;role - Réseau local privé
            [1] => netgear;00:0F:B5:B1:B0:28;192.168.0.1;Routeur/Passerelle
            [2] => srv-2;00:00:00:00:00:02;192.168.0.2;Réservé service
            [3] => ... etc ...
            [4] => morpho;C0:FF:D4:B0:B8:C6;192.168.0.8;Hotspot WIFI
            [5] => vulcain;00:60:97:A6:FF:89;192.168.0.9;Serveur FTP/Web local
            [6] => samia;00:01:E6:35:B7:49;192.168.0.10;Imprimante réseau
            [7] => Kallima;B0:6E:BF:2F:CF:B4;192.168.0.11;PC fixe MC
            [8] => zigzag;98:3B:16:18:94:D5;192.168.0.12;Tablette MC
            [9] => hepialus;00:00:00:00:00:13;192.168.0.13;Huawei P30 MC
            [10] => ysandra;3C:CD:5D:83:E0:BC;192.168.0.14;Portable MC
            [11] => ... 192.168.0.15 à 20 : réservé MC ...
            [12] => cypris;00:E0:4C:39:4C:4D;192.168.0.21;PC fixe Pierre
            [13] => ... 192.168.0.21 à 30 : Réservé Pierre ...
            [14] => guest-31 à 35;;192.168.0.31 à 35;Invité
        )

    [1] => Array
        (
            [0] => # hostname;mac@;ip;role - DMZ du réseau local
            [1] => monarque;01:02:03:04:05:06;192.168.10.226;Serveur Web
            [2] => rethenor;B8:27:EB:85:20:13;192.168.10.227;Serveur FTP
            [3] => ... 192.168.10.228 à 192.168.10.230 : réservé services ...
        )

)


Merci beaucoup pour ton aide. Question résolue.
0