Bonjour, je t'expliquerais tout d'abord la récursivité et en suite la technique pour utiliser la récursivité pour compter dans des dossiers et sous dossiers.
La récursivité est une technique qui permet d'appliquer le même algorithme à des objets ayant la même nature et dont le nombre est inconnu par le programme. De ce fait, le programme doit répéter cet algorithme autant de fois qu'il rencontre d'objets traitables.
Le risque de la récursivité est l'infinité de répétition ce qui peut saturer la pile d'exécution et planter la machine. C'est pour cela que le programme récursif doit contenir une condition de sortie qui permet de l'arrêter.
La récursivité ressemble à une boucle While sauf que c'est une procédure qui appelle elle-même.
Exemple : Calculer le factoriel d'un nombre.
Factoriel de 4 = 4x3x2x1 = 24
Factoriel de 10 = 10x9x8x7x6x5x4x3x2x1 = 3 628 800
Donc, le factoriel est la multiplication de N et N-1 jusqu'à 1. La procédure qui se répète ici est : N x N-1 et la condition d'arrêt est quand N=1 pour éviter zéro.
Cette procédure est donc récursive et peut s'écrire :
Programme :
Factoriel.php
<?php
//Calcul du Factoriel
function factoriel($N) {
//calculer factoriel si N>1
if ($N>1) {
//dans ce cas: appeler récursivement la fonction factoriel pour calculer celui de $N-1
return ($N * factoriel($N-1));
}
//tester la condition d'arrêt
if ($N==1) {
return $N;
}
//convention: factoriel de zéro=1
if ($N==0) { return 1; }
}
// Programme principal
echo 'Factoriel de 4 = ' . factoriel(4);
echo '<br>';
echo 'Factoriel de 10 = ' . factoriel(10);
?>
Déroulement du programme:
Etat1 : à l'instruction
echo 'Factoriel de 4 = ' . factoriel(4); la fonction
factoriel(4) est appelée:
Etat2 : $N=4, l'instruction
return ($N * factoriel($N-1)); est exécutée car $N >1 donc la fonction
factoriel($N-1) est appelée pour $N-1=3.
Etat3 : $N=3, l'instruction
return ($N * factoriel($N-1)); est exécutée car $N >1 donc la fonction
factoriel($N-1) est appelée pour $N-1=2.
Etat4 : $N=2, l'instruction
return ($N * factoriel($N-1)); est exécutée car $N >1 donc la fonction
factoriel($N-1) est appelée pour $N-1=1.
Etat5 : $N=1, l'instruction
return $N; est exécutée car $N=1 donc
la fonction actuelle se termine et retourne la valeur 1 à celle de l'Etat4.
Etat4 : $N=2, l'instruction
return ($N * factoriel($N-1)); est exécutée et
la fonction de l'Etat4 se termine et retourne la valeur (2*1)=2 à celle de l'Etat3.
Etat3 :$N=3, l'instruction
return ($N * factoriel($N-1)); est exécutée et
la fonction de l'Etat3 se termine et retourne la valeur (3*2)=6 à celle de l'Etat2.
Etat2 :$N=4, l'instruction
return ($N * factoriel($N-1)); est exécutée et
la fonction de l'Etat2 se termine et retourne la valeur (4*6)=24 à celle de l'Etat1.
Etat1 : à l'instruction
echo 'Factoriel de 4 = ' . factoriel(4); la fonction
factoriel(4) reçoit finalement la valeur 24 qui s'affiche donc.
Bien que le sujet n'est pas de développer le factoriel, voici le cas amélioré qui prend en compte le factoriel des suites positives, négatives et le zéro:
<?php
//Calcul du Factoriel
function factoriel($N) {
//calculer factoriel si N>1
if (abs($N)>1) {
//dans ce cas: appeler récursivement la fonction factoriel pour calculer celui de $N précédent
$N_precedent = $N<0 ? $N+1 : $N-1; //prise en compte des suites positives et négatives
return ($N * factoriel($N_precedent));
}
//tester la condition d'arrêt
if (abs($N)==1) {
return $N;
}
//convention: factoriel de zéro=1
if (abs($N)==0) { return 1; }
}
// Programme principal
echo 'Factoriel de 0 = ' . factoriel(0);
echo '<br>';
echo 'Factoriel de 4 = ' . factoriel(4);
echo '<br>';
echo 'Factoriel de -4 = ' . factoriel(-4);
echo '<br>';
echo 'Factoriel de 9 = ' . factoriel(9);
echo '<br>';
echo 'Factoriel de -9 = ' . factoriel(-9);
?>
Conclusion:
Un procédure récursive est une procédure qui appelle elle-même sous forme d’empilation de procédures sans prendre le risque de boucler à l'infini, elle contient donc une condition d'arrêt qui permet à la dernière instance de la pile de se terminer pour retourner à l'instance qui la précède jusqu'à arrivée à la surface d'exécution du programme principal.
Voila. Mintenant qu'on a compris ce qu'est la récursivité, il va falloir l'utiliser pour le cas d'école de lecture d'un dossier qui peut contenir une infinité de sous-dossiers qui eux-mêmes peuvent en contenir d'autres.
L'algorithme principal est celui qui décrit pourquoi lire un dossier, la réponse est pour traiter ses fichiers et parcourir ses sous-dossiers etc...
La récursivité ici est le fait de devoir parcourir une infinité de dossiers pour faire la même chose, c'est à dire : traiter les fichiers et parcourir les sous-dossiers. Mais que ça s'arrête, il faut une condition d'arrêt. La plus logique est quand le traitement ne trouve plus de sous-dossier à parcourir.
Voici donc le programme:
lire_dossier.php
<pre>
<?php
//fonction qui parcourt un dossier et découvrir son contenu
function explorer($dossier) {
//variable globale vue par toutes les fonctions
global $result_list;
//ouvrir le dossier
if ($dh = @opendir($dossier)) {
//parcourir les objets fichiers ou sous-dossiers du dossier
while (($objet = @readdir($dh)) !== false) {
//éviter les marques du parent
if ($objet !== '.' && $objet !== '..') {
//nom complet de l'objet
$objet = $dossier .'/'. $objet;
//verfier s'il s'agit d'un fichier
if (is_file($objet)) {
//enregistrer le fichier comme objet trouvé dans ce dossier
$result_list['dossiers'][$dossier][] = $objet;
}
//verfier s'il s'agit d'un sous-dossier
elseif (is_dir($objet)) {
//parcourir ce sous-dossier pour découvrir son contenu
explorer($objet);
}
}
}
}
//compte le nombre de total des fichiers
$result_list['nbre_fichiers'] += count($result_list['dossiers'][$dossier]);
//fin de la fonction
return $result_list;
}
//test de la fonction
$result_list = explorer('c:/wamp/www/test');
print_r($result_list);
echo "<br>";
//stats
echo "Le nombre total des fichiers est : ". $result_list['nbre_fichiers'];
echo "<br>";
echo "Le nombre total de dossiers est : ". count($result_list['dossiers']);
echo "<br>";
foreach($result_list['dossiers'] as $dossier=>$list_fichiers){
echo "Le nombre de fichiers du dossier '". $dossier ."' est : " . count($list_fichiers);
echo "<br>";
}
?>
</pre>
J'en ai profité pour lister et compter les fichiers

Voila.