PHP : Lecture de fichier html ou xml

Présentation

But

Générer automatiquement la liste des ponts disponibles sur notre site afin de n'avoir qu'a ajouter les nouvelles pages sans toucher au sommaire.

Activité

Il va falloir :

Déterminer les différentes pages (décrivant un pont) placées sur notre site.

Trouver pour chaque page le nom du pont concerné.

Trier la liste des ponts dans l'ordre alphabétique pour plus de clarté.

Afficher la liste sur la page.

Connaissances et savoir faire

Revoir le cours sur le PHP

Connaissances supplémentaires

Il existe de nombreuses bibliothèques PHP contenant des fonctions utiles aux différentes tâches à réaliser. Voir sur Références PHP le détail des différentes fonctions ci-dessous grâce a son moteur de recherche.

Parcourir le système de fichier

Il faut donc parcourir le système de fichier de notre site pour traiter tous les fichiers HTML sauf index.html.

Le système de fichier correspond à l'arborescence des adresses URL ( (dossier /) fichier.extension).

Le dossier courant peut être représenté par un point '.' et le dossier parent par '..'.

Un dossier est un espace de données qui contient des pointeurs sur le contenu des fichiers.

Un fichier est identifié par son chemin (liste des dossiers successifs, un nom et une extension (fonction de son contenu).

Si un fichier est connu, on peut y accéder directement : fopen ($chemin, 'r'); (r = lecture et w = écriture).

Pour parcourir ou chercher les fichier d'un dossier, il est nécessaire de :

Pointer sur le dossier courant (ou sont enregistrées nos pages) : $dir = opendir($chemin)

Lire les fichiers qui s'y trouvent : $fic = readdir($dir)

Décomposer le nom du fichier dans un tableau : $tabinfo = pathinfos($fic)

Conserver les fichiers qui contiennent du HTML sauf index.html ($tabinfo[“extension”] et $tabinfo[“basename”])

Coup de pouce

<?php // Définir une variable pointant sur notre site (la position de la page courante est symbolisée par un point) // Opendir fourni un pointeur sur un dossier et sélectionne son 1er fichier. $site = opendir("."); // lire tout les fichiers les un après les autres (réponse false si tous les fichiers ont été lus) // readdir fourni le pointeur sur le fichier courant du dossier et sélectionne suivant sinon "false". while (($fichier = readdir($site)) != false) { // ne conserver que les fichiers d'extension HTML // pathinfos fourni dans un tableau des informations sur un fichier dont l'extension et le nom de base $info = pathinfo($fichier); if ($info["extension"] == "html") { // ne pas conserver le fichier index.html s'il existe if ($info["basename"] != "index.html") { ... } } } ?>

Lire le contenu d'un fichier HTML

Nous avons trouvé le fichier concernant un pont. Pour connaître le nom nom du pont, il faut lire le contenu de la balise <body><h2><a>.

Le HTML est un langage de balisage issu du XML. Il existe des fonctions spécifiques pour lire le contenu des balises.

Lire un fichier texte :

Ouvrir le fichier : $fic = fopen($chemin, 'r');

Contrôler s'il reste des lignes à lire : feof($fic); retourne true/vrai s'il n'y a rien à lire.

Lire une ligne (terminée par un retour à la ligne \n) : $ligne = fgets($fic);

fermer le fichier si l'on n'en a plus besoin : fclose($fich);

Lire un fichier texte mais balisé :

Ouvrir chaque fichier HTML : $fic = SimpleXMLElement($texte/chemin, 0, true) le paramètre à true, indique une adresse URL (tout un fichier) et pas un texte balisé (une ligne déjà lue).

Récupérer le nom du pont : $fic->body->h2->a.

La variable $fic obtenue grâce à SimpleXMLElement contient un objet spécial qui pourra être vu dans une leçon sur la programmation objet. Pour lire le contenu d'une balise, il faut partir de la première et utiliser des flèches. La documentation de SimpleXML indique beaucoup d'autres choses possibles.

Coup de pouce

// Ouvre le fichier pour en lire le contenu ($page = contenue de la balise HTML) $page = new SimpleXMLElement('./' . $fichier, 0, TRUE); // Récupère le nom du pont dans la balise et l'ajoute dans une liste (tableau) $nom = $page->body->h2->a;

Les tableaux

Un tableau est un objet particulier contenant une liste de clé->valeur. Une fois le tableau créé, je peux ajouter de nouvelle clé->valeur ou en lire le contenue. Les clés (série de nombres débutant à 0 ou série de mots uniques dans la liste) permettent d'accéder aux différentes valeurs. Les tableaux peuvent être “multidimensionnel” (la valeur est elle même un tableau). Ils peuvent aussi être parcourus de manière itérative.

Il faut :

Créer un tableau pour contenir la liste (avant d'accéder au système de fichier) : $tab = array();.

Ajouter dans la liste, pour chaque pont, son nom et son fichier : $tab[] = array(“nom” => $nom, “fich” => $info[“basename”]);

Trier la liste dans l'ordre alphabétique (lorsque tous les fichiers ont étés lus) : $tab->asort();

Affichage de chaînes de caractères

Nous avons vu que 2 chaînes de caractères pouvaient être concaténées grâce à l'opérateur '.' mais il existe aussi de nombreuses fonctions comme : chercher la position d'une sous chaîne, extraire une sous chaîne, convertir la chaîne (minuscule/majuscule ...), remplacer une partie de chaîne, formater une chaîne ... Concernant l'affichage d'un résultat, c'est sa mise en forme qui nous importe le plus.

Indiquer le nombre d'élément d'une liste : count($liste);

Créer une boucle pour traiter tous les éléments de la liste des ponts : foreach()

Afficher chaque élément de la liste de manière formatée : printf()

Coup de pouce

// Afficher le nombre de pont echo "\t<p>La collection possède " . count($liste) . " ponts :</p>\n"; // Début de liste et parcourir la liste des ponts echo "\t<ul>\n"; foreach ($ponts as $pont) // créer les balises HTML pour mettre en place chaque élément de la liste de liens utiles printf("\t\t<li><a href='%s'>%s</a></li>\n", $pont["fic"], $pont["nom"]); // Fin de la liste echo "\t</ul>\n";

Pour finir

Ne pas oublier d'enregistrer ce nouveau fichier sous le nom de “index.php” puisqu'il contient du PHP à interpréter.

Corriger le lien de retour de chaque page concernant un pont de “index.html” en “index.php”.

Tester et corriger le code si besoin.

<WRAP round download>

Solution complète

</WRAP

<fich php index.php> <head> <meta charset="UTF-8" /> <title>Ponts du monde</title> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="stylesheet" type="text/css" href="style1.css"> </head> <body class="principal"> <h1>Ponts du monde</h1> <p>Ce site présente les pont les plus remarquables dans le monde. Il est destiné à s'agrandir en fonction de mes découvertes.</p> <h2>Liste des ponts</h2> <?php // Définir une variable pointant sur notre site (la position de la page courante est symbolisée par un point) // Opendir fourni un pointeur sur un dossier et sélectionne son 1er fichier. $site = opendir("."); // Créer la liste pour contenir les ponts $liste = array(); // lire tout les fichiers les un après les autres (réponse false si tous les fichiers ont été lus) // readdir fourni le pointeur sur le fichier courant du dossier et sélectionne suivant sinon "false". while (($fichier = readdir($site)) != false) { // ne conserver que les fichiers d'extension HTML // pathinfos fourni dans un tableau des informations sur un fichier dont l'extension et le nom de base $info = pathinfo($fichier); if ($info["extension"] == "html") { // ne pas conserver le fichier index.html s'il existe if ($info["basename"] != "index.html") { // Ouvre le fichier pour en lire le contenu ($page = contenue de la balise HTML) $page = new SimpleXMLElement('./' . $fichier, 0, TRUE); // Récupère le nom du pont dans la balise et l'ajoute dans une liste (tableau) $liste[] = array("nom" => $page->body->h2->a, "fich" => $info["filename"]); } } } // Trie alphabétiquement la liste asort($liste); // Afficher le nombre de pont echo "\t<p>La collection possède " . count($liste) . " ponts :</p>\n"; // Début de liste et parcourir la liste des ponts echo "\t<ul>\n"; foreach ($liste as $pont) // créer les balises HTML pour mettre en place chaque élément de la liste de liens utiles printf("\t\t<li><a href='%s'>%s</a></li>\n", $pont["fich"], $pont["nom"]); // Fin de la liste echo "\t</ul>\n"; ?> </body> </fich>

Pour aller plus loin

Cette 1ere page PHP nous permet de ne plus avoir à modifier notre page “index” à chaque ajout de nouveau pont.

Pour aller plus loin avec les sites dynamiques, il faudra des compétences :

en base de données SQL pour stocker les informations sur les ponts,

en formulaire HTML pour saisir les informations de chaque pont,

gestion des bases de données à partir du PHP.

La base de donnée nous permettra :

de stocker toutes les informations des ponts non plus dans une page HTML à écrire pour chaque pont mais directement en base de donnée à partir d'un formulaire,

de générer le sommaire directement à partir de chaque pont contenu dans la base,

d'afficher n'importe quel pont à partir d'une page unique.

Notre site n'aura besoin que de 3 pages (index, formulaire, affichage) quel que soit le nombre de ponts. Sa maintenance et son évolution en sera grandement facilité.

C'est cet ensemble HTML, CSS, SQL et PHP qui ont permis le développement des sites marchands et des autres sites utilisant la génération automatisée des pages .