PHP offre un ensemble de fonctions pour gérer les dossiers sur le disque du serveur (ou un disque accessible depuis le serveur).

Certaines opérations ne sont cependant pas possibles directement et nous devons les prendre en charge avec le développement de nos propres fonctions de gestion qui utilisent très souvent des mécanismes récursifs.

Pour les exemples, nous utiliserons l'aborescence de dossiers ci-contre.

Cet aborescence se trouve dans le dossier test du tutoriel. Vous pouvez voir son contenu avec le bouton dans la barre de menu du tutoriel.

Si vous ne voyez pas cet aborescence, ou si vous voulez la ré-initialiser utilisez ce script.

### Contenu d'un dossier

Pour lire le contenu d'un dossier, nous procédons comme pour la lecture d'un fichier ligne à ligne et nous devons exécuter les opérations suivantes :

- ouvrir le dossier avec la fonction opendir() qui renvoie un pointeur sur la ressource (le dossier physique), ou FALSE si le dossier ne peut pas être ouvert (pas les permissions, mauvais nom, inexistant, etc.). La fonction accepte comme seul argument le nom du dossier à ouvrir (avec un chemin absolu ou relatif).
- effectuer une boucle pour lire un à un les éléments contenus dans le dossier avec la fonction readdir() qui renvoie le nom des éléments (fichiers ou sous-dossiers). Quand tous les éléments ont été lus, la fonction renvoie FALSE.
- fermer le dossier avec la fonction closedir() qui va aussi libérer le pointeur de ressource.

L'exemple suivant affiche le contenu du dossier test_repert.

Exemple : contenu d'un dossier
<?php ob_start(); require('bib_fonctions.php'); htmlDebut('Contenu d\'un dossier'); $nom = 'test_repert'; htmlInfo("Contenu du dossier $nom"); // Ouverture du dossier $dossier = @opendir($nom); if (! $dossier) { exit('Erreur dans l\'ouverture du dossier'); } // Boucle de lecture du dossier while ($elem = readdir($dossier)) { echo '<br>', $elem; } // Fermeture du dossier @closeDir($dossier); htmlFin(); ?>

La boucle de lecture du contenu du dossier est du même genre que celle utilisée pour lire les résultats d'une requête SELECT :

    while ($elem = readdir($dossier)) {
    	...
    }

- la fonction readdir() est exécutée
- son résultat est affecté à la variable $elem
- si la valeur de $elem est évaluée comme TRUE le bloc while est exécuté,
- sinon la boucle while est arrêtée.

L'affichage des résultats du script nous permet de remarquer trois choses :

- la fonction readdir() renvoie les noms des fichiers et des sous-dossiers sans faire de distinction,
- les éléments (fichiers et sous-dossiers) sont affichés par ordre alphabétique ou dans n'importe quel ordre,
- les dossiers particuliers . (point - le dossier en cours) et .. (double point - le dossier parent) sont renvoyés par la fonction readdir() et apparaissent dans la liste.

Modifions le script pour ne pas afficher (et éventuellement traiter) les dossiers particuliers . et ..

Exemple : contenu d'un dossier
<?php ob_start(); require('bib_fonctions.php'); htmlDebut('Contenu d\'un dossier'); $nom = 'test_repert'; htmlInfo("Contenu du dossier $nom"); // Ouverture du dossier $dossier = @opendir($nom); if (! $dossier) { exit('Erreur dans l\'ouverture du dossier'); } // Boucle de lecture du dossier while ($elem = readdir($dossier)) { if ($elem == '.' || $elem == '..') { continue; } echo '<br>', $elem; } // Fermeture du dossier @closeDir($dossier); htmlFin(); ?>

### Boucle de lecture

La boucle while ($elem = @readdir($dossier)) doit être améliorée car elle ne fonctionne pas correctement dans tous les cas.

En effet, si un élément (fichier ou sous-dossier) s'appelle 0 ou false, la boucle s'arrêtera car elle croiera que c'est le résultat de la fonction readdir() et pas le nom de l'élément.

Regardons ce qui se passe si nous essayons de lire le contenu du dossier test_repert/export qui contient un dossier appelé 0.

Exemple : contenu d'un dossier
<?php ob_start(); require('bib_fonctions.php'); htmlDebut('Contenu d\'un dossier'); $nom = 'test_repert/export'; htmlInfo("Contenu du dossier $nom"); // Ouverture du dossier $dossier = @opendir($nom); if (! $dossier) { exit('Erreur dans l\'ouverture du dossier'); } // Boucle de lecture du dossier while ($elem = readdir($dossier)) { if ($elem == '.' || $elem == '..') { continue; } echo '<br>', $elem; } // Fermeture du dossier @closeDir($dossier); htmlFin(); ?>

La boucle while ($elem = @readdir($dossier)) ne fonctionne pas, et s'arrête dés qu'elle rencontre le dossier appelé 0.
Nous devons utiliser l'opérateur d'inégalité stricte !== et la syntaxe suivante pour tester la fin de la boucle :
while (($elem = @readdir($dossier)) !== FALSE)

Exemple : contenu d'un dossier
<?php ob_start(); require('bib_fonctions.php'); htmlDebut('Contenu d\'un dossier'); $nom = 'test_repert/export'; htmlInfo("Contenu du dossier $nom"); // Ouverture du dossier $dossier = @opendir($nom); if (! $dossier) { exit('Erreur dans l\'ouverture du dossier'); } // Boucle de lecture du dossier while (($elem = readdir($dossier)) !== FALSE) { if ($elem == '.' || $elem == '..') { continue; } echo '<br>', $elem; } // Fermeture du dossier @closeDir($dossier); htmlFin(); ?>