6.Le langage PHP

6.11.Fichiers et répertoires

6.11.1.Lire un fichier ligne par ligne

Pour lire un fichier, il faut d'abord l'ouvrir grâce à la fonction fopen(). A l'issue de l'ouverture, on récupère un pointeur (pointant sur le début du fichier) et on lit les lignes grâce à fgets() jusqu'à atteindre la fin du fichier que l'on détecte grâce à feof()
<?php
    // Ouverture du fichier en lecture [option "r"]
    // et récupération d'un pointeur (ou descripteur de fichier)
    // Ici, j'ai utilisé une petite astuce afin d'afficher
    // le contenu du fichier constituant ce script
    // j'ai donc utilisé __FILE__ au lieu de spécifier
    // un fichier par "/chemin/monfichier"
    // Le @ n'est absolument pas obligatoire mais il
    // evite l'affichage d'un message d'erreur (non controlé)
    // dans le cas où le fichier n'existe pas.
    $fd = @fopen(__FILE__,"r");
    
    // si fopen retourne faux c'est que le fichier
    // ne peut être ouvert en lecture
    if (!$fd) die("Impossible d'ouvrir le fichier");
    
    $i = 1; // compteur de ligne
    
    // Lorsque nous atteindrons la fin du fichier
    // foef($fd) retournera faux
    // et la boucle while s'arrêtera
    while (!feof($fd)) {
    
        // Il est temps de lire une ligne du fichier
        // et en tout cas au maximum 1024 caractères
        $ligne = fgets($fd, 1024);
        
        // Si la fin du fichier n'est pas atteinte
        // On peut maintenant afficher la ligne
        if (!feof($fd)) echo "Ligne $i : ".htmlEntities($ligne)."<br/>";
        $i++;
    }
    
    // On a fini, on ferme !!
    fclose($fd);
?> 
Exemple:
Ligne 1 : <?php
Ligne 2 : // Ouverture du fichier en lecture [option "r"]
Ligne 3 : // et récupération d'un pointeur (ou descripteur de fichier)
Ligne 4 : // Ici, j'ai utilisé une petite astuce afin d'afficher
Ligne 5 : // le contenu du fichier constituant ce script
Ligne 6 : // j'ai donc utilisé __FILE__ au lieu de spécifier
Ligne 7 : // un fichier par "/chemin/monfichier"
Ligne 8 : // Le @ n'est absolument pas obligatoire mais il
Ligne 9 : // evite l'affichage d'un message d'erreur (non controlé)
Ligne 10 : // dans le cas où le fichier n'existe pas.
Ligne 11 : $fd = @fopen(__FILE__,"r");
Ligne 12 :
Ligne 13 : // si fopen retourne faux c'est que le fichier
Ligne 14 : // ne peut être ouvert en lecture
Ligne 15 : if (!$fd) die("Impossible d'ouvrir le fichier");
Ligne 16 :
Ligne 17 : $i = 1; // compteur de ligne
Ligne 18 :
Ligne 19 : // Lorsque nous atteindrons la fin du fichier
Ligne 20 : // foef($fd) retournera faux
Ligne 21 : // et la boucle while s'arrêtera
Ligne 22 : while (!feof($fd)) {
Ligne 23 :
Ligne 24 : // Il est temps de lire une ligne du fichier
Ligne 25 : // et en tout cas au maximum 1024 caractères
Ligne 26 : $ligne = fgets($fd, 1024);
Ligne 27 :
Ligne 28 : // Si la fin du fichier n'est pas atteinte
Ligne 29 : // On peut maintenant afficher la ligne
Ligne 30 : if (!feof($fd)) echo "Ligne $i : ".htmlEntities($ligne)."<br/>";
Ligne 31 : $i++;
Ligne 32 : }
Ligne 33 :
Ligne 34 : // On a fini, on ferme !!
Ligne 35 : fclose($fd);
Ligne 36 : ?>
Il est également possible de spécifier un nom de fichier par une url ex: "http://www.site.com/chemin/fichier".

6.11.2.Récupérer le contenu d'un fichier dans un tableau

Il existe également une fonction file() permettant de mettre l'ensemble du fichier dans un tableau.
<?php
    // ouverte, lecture , fermeture du fichier et stockage dans un tableau
    // Ici, aussi, j'ai utilisé __FILE__ qui représente le fichier courant
    // mais dans une utilisation courante on utilisera quelque chose comme
    // "/chemin/nomdufichier"
    $tableau = file(__FILE__);
    
    // affichage du contenu du tableau
    for ($i=0; $i<count($tableau); $i++) {
        echo "ligne $i : " . htmlEntities($tableau[$i]) . "<br/>";
    }
?>
Exemple:
ligne 0 : <?php
ligne 1 : // ouverte, lecture , fermeture du fichier et stockage dans un tableau
ligne 2 : // Ici, aussi, j'ai utilisé __FILE__ qui représente le fichier courant
ligne 3 : // mais dans une utilisation courante on utilisera quelque chose comme
ligne 4 : // "/chemin/nomdufichier"
ligne 5 : $tableau = file(__FILE__);
ligne 6 :
ligne 7 : // affichage du contenu du tableau
ligne 8 : for ($i=0; $i<count($tableau); $i++) {
ligne 9 : echo "ligne $i : " . htmlEntities($tableau[$i]) . "<br/>";
ligne 10 : }
ligne 11 : ?>
Si le but est simplement d'afficher le contenu du fichier alors vous pourrez avantageusement opter pour la fonction readfile(nomdufichier)

6.11.3.Lire un fichier paquet par paquet

La lecture d'un fichier ligne par ligne convient aux fichiers textes (dit fichiers ASCII) par compte cela ne convient pas pour les fichiers binaires (ex: les images). Même si là encore, il convient d'ouvrir le fichier grâce à fopen(), la lecture, elle, se fera par l'intermédiaire de fread(), et à nouveau la fermeture par fclose().
En guise d'exemple, nous n'utiliserons pas de fichier binaire (qu'il serait difficile de représenter) mais un fichier texte (le script lui-même) ce qui est suffisant pour constater que les fins de ligne ne sont pas prisent en compte par la fonction fread().
<?php
    // Ouverture du fichier en lecture [option "r"]
    // et récupération d'un pointeur (ou descripteur de fichier)
    // Ici, j'ai utilisé une petite astuce afin d'afficher
    // le contenu du fichier constituant ce script
    // j'ai donc utilisé __FILE__ au lieu de spécifier
    // un fichier par "/chemin/monfichier"
    // Le @ n'est absolument pas obligatoire mais il
    // evite l'affichage d'un message d'erreur (non controlé)
    // dans le cas où le fichier n'existe pas.
    $fd = @fopen(__FILE__,"r");
    
    // si fopen retourne faux c'est que le fichier
    // ne peut être ouvert en lecture
    if (!$fd) die("Impossible d'ouvrir le fichier");
    
    $i = 1; // compteur de paquets
    
    // Lorsque nous atteindrons la fin du fichier
    // foef($fd) retournera faux
    // et la boucle while s'arrêtera
    while (!feof($fd)) {
    
        // Il est temps de 80 caractères (si possible)
        $paquet = fread($fd, 80);
        
        // Si la fin du fichier n'est pas atteinte
        // On peut maintenant afficher la ligne
        if (!feof($fd)) echo "Paquet $i : ".htmlEntities($paquet, ENT_COMPAT, "UTF-8")."<br/>";
        $i++;
    }
    
    // On a fini, on ferme !!
    fclose($fd);
?> 
Exemple:
Paquet 1 : <?php // Ouverture du fichier en lecture [option "r"] // et récupérati
Paquet 2 : on d'un pointeur (ou descripteur de fichier) // Ici, j'ai utilisé une petit
Paquet 3 : e astuce afin d'afficher // le contenu du fichier constituant ce script
Paquet 4 : // j'ai donc utilisé __FILE__ au lieu de spécifier // un fichier par "/che
Paquet 5 : min/monfichier" // Le @ n'est absolument pas obligatoire mais il // evit
Paquet 6 : e l'affichage d'un message d'erreur (non controlé) // dans le cas où le fi
Paquet 7 : chier n'existe pas. $fd = @fopen(__FILE__,"r"); // si fopen retourn
Paquet 8 : e faux c'est que le fichier // ne peut être ouvert en lecture if (!$fd)
Paquet 9 : die("Impossible d'ouvrir le fichier"); $i = 1; // compteur de paquets
Paquet 10 : // Lorsque nous atteindrons la fin du fichier // foef($fd) retourne
Paquet 11 : ra faux // et la boucle while s'arrêtera while (!feof($fd)) {
Paquet 12 : // Il est temps de 80 caractères (si possible) $paquet = fread($fd,
Paquet 13 : 80); // Si la fin du fichier n'est pas atteinte // On
Paquet 14 : peut maintenant afficher la ligne if (!feof($fd)) echo "Paquet $i : ".ht
Paquet 15 : mlEntities($paquet, ENT_COMPAT, "UTF-8")."<br/>"; $i++; } /
Il est également possible de spécifier un nom de fichier par une url ex: "http://www.site.com/chemin/fichier".

6.11.4.Ecrire dans un fichier

Pour écrire dans un fichier, il faut: ouvrir le fichier en écriture grâce à fopen() et l'option "w" ou "a" (mode ajout [append]), écrire par l'intermédiaire de fwrite(), et à nouveau fermer par fclose().
<?php
    // Ouverture du fichier en écriture [option "w", ou "a" pour le mode ajout]
    // et récupération d'un pointeur (ou descripteur de fichier)
    // Le @ n'est absolument pas obligatoire mais il
    // evite l'affichage d'un message d'erreur (non controlé)
    // dans le cas où le fichier ne peut être créé.
    $fd = @fopen("chapfile3_1.tmp", "w");

    // si fopen retourne faux c'est que le fichier
    // ne peut être ouvert en écriture
    if (!$fd) die("Impossible d'ouvrir le fichier");

    // juste une boucle d'écriture (totalement bidon)
    for ($i=0; $i<20; $i++) {
        // j'écris
        fwrite($fd, "Encore une ligne pour rien dire");
    }

    // On a fini, on ferme !!
    fclose($fd);
?>
Il est maintenant temps de voir ce que l'on peut faire avec les répertoires.

6.11.5.Lister les fichiers d'un répertoire

Lister le contenu d'un répertoire s'apparente un peu à la lecture d'un fichier. On commence par récupérer un pointeur sur le premier fichier du répertoire et on déplace le pointeur de fichier en fichier jusqu'à atteindre la fin du répertoire.
<?php
    // Définition du chemin à explorer (adaptez a votre environnement)
    $homedir = dirname($_SERVER["DOCUMENT_ROOT"])."/filedirexample";
    
    // "ouverture" du répertoire
    $dir = @opendir($homedir);
    
    // Récupération d'un pointeur sur le premier
    // fichier (ou sous-répertoire) du répertoire grâce à readdir.
    // Lorsque nous aurons atteint la fin de répertoire
    // readdir retournera faux par conséquent
    // la boucle s'arrêtera
    while ($file = readdir($dir)) {
        // Affichage du nom du fichier (ou sous-répertoire)
        echo "$file<br/>";
    }
    
    // C'est fini. On ferme !
    closedir($dir);
?>
Exemple:
Comme vous pouvez le voir sur cet exemple, parmi les répertoires et fichiers, on trouve "." (représentant le répertoire courant) et ".." (représentant le répertoire supérieur). Bien souvent, il faut les ignorer, d'où le nouveau code.
<?php
    // Définition du chemin à explorer (adaptez a votre environnement)
    $homedir = dirname($_SERVER["DOCUMENT_ROOT"])."/filedirexample";
    
    // "ouverture" du répertoire
    $dir = @opendir($homedir);
    
    // Récupération d'un pointeur sur le premier
    // fichier (ou sous-répertoire) du répertoire grâce à readdir.
    // Lorsque nous aurons atteint la fin de répertoire
    // readdir retournera faux par conséquent
    // la boucle s'arrêtera
    while ($file = readdir($dir)) {
        // Affichage du nom du fichier (ou sous-répertoire)
        // sauf "." et ".."
        if (($file != ".") && ($file != "..")) echo "$file<br/>";
    }
    
    // C'est fini. On ferme !
    closedir($dir);
?>
Exemple:
Voilà, qui est mieux. Mais parfois, il est utile également d'accéder à la liste des fichiers dans les sous-répertoires. Allez, suivez moi dans le chapitre suivant.

6.11.6.... et de ses sous-répertoires

Pour cela nous devons lister le contenu du répertoire désigné (Cf. chapitre précédent) mais en plus à chaque fois que nous rencontrons un répertoire nous devons (ré-)appliquer ce même algorithme. C'est ce que l'on appelle une fonction récursive.
<?php

// La fonction d'exploration
function explore($homedir) {
    
    $dir = openDir($homedir);

    while ($file = readDir($dir)) {
        if (($file!=".")&&($file!="..")) {
            // Est-ce que $file est un répertoire ?
            // Pour le savoir il suffit d'appeler is_dir()
            // mais attention n'oublions pas d'ajouter
            // le chemin au nom du fichier
            if (is_dir("$homedir/$file")) {
                // oui ? alors explorons-le
                // REM: On pourrait en plus l'afficher
                explore("$homedir/$file");
            } else {
                // sinon, c'est un fichier et on l'affiche
                $cheminComplet = $homedir."/".$file;
                // (mais sans le chemin $_SERVER["DOCUMENT_ROOT"]
                echo substr($cheminComplet, strlen(dirname($_SERVER["DOCUMENT_ROOT"]))).
                     "<br/>";
            }
        }
    }
    
    // C'est fini. On ferme !
    closeDir($dir);
}

// Définition du chemin à explorer (adaptez a votre environnement)
$repertoire = dirname($_SERVER["DOCUMENT_ROOT"])."/filedirexample";

// L'appel à la fonction
explore($repertoire);
?>
Exemple:
Ici vous pouvez apprendre :
Forum PHP
Version imprimable: imprimer