PHP - Portée d'1 variable (array) hors d'1 simple "while"

PHP - Portée d'1 variable (array) hors d'1 simple "while" - PHP - Programmation

Marsh Posté le 09-09-2008 à 14:08:17    

Bonjour ! Je suis nouveau ici. J'espere ne pas débarquer trop. J'ai parcouru le forum pour y trouver un MSG traitant de ce qui m'occupe, mais il semble que personne n'est aussi cave que moi pour poser une question aussi basique : Comment acceder à une variable de type array n'importe où dans un script ?
 
Voici une boucle while qui je pense, risque de faire grincer quelques dents. Il s'agit d'un prototype, je cherche une solution pratique à mon probleme :
 
Je souhaite afficher une liste de répertoires/sous reps à partir d'une url donnée, mettons la racine du site, uniquement si lesdits répertoires contiennent des mp3.
 
Donc si la racine du site contient :
 
/img/ => /img/somegif.gif, /img/somejpeg.jpg
/cgi-bin/ => /cgi-bin/somescript.py, /cgi-bin/somescript.php
/plop/
  /plop/someblackmetalshit/ => /plop/mp3/heaven.mp3, /plop/mp3/hell.mp3, /plop/mp3/purgatory.mp3
  /plop/badaboum/ => /plop/mp3/tirlipanpan.mp3, /plop/mp3/surle.mp3, /plop/mp3/chihuahua.mp3
/vide/ => atiensnon.txt
/residents/margaret_freman.mp3
 
Ma fonction (enfin, là c juste une boucle while *dans* une fonction, récupérée sur le net) devrait retourner :
/plop/someblackmetalshit/ , /plop/badaboum/ , /residents/
(Notez qu'elle doit exclure "/plop/" vous suivez ?)
 
Voilà la boucle, faites sortir les enfants :
 

Code :
  1. function recursive_readdir ($dir) {
  2. $goodList = array();
  3. $dir = rtrim ($dir, '/'); // on vire un eventuel slash mis par l'utilisateur de la fonction a droite du repertoire
  4. if (is_dir ($dir)) // si c'est un repertoire
  5.  $dh = opendir ($dir); // on l'ouvre
  6. else {
  7.  echo $dir, ' n\'est pas un repertoire valide'; // sinon on sort! Appel de fonction non valide
  8. exit;
  9. }
  10. while (($file = readdir ($dh)) !== false ) {
  11.  if ($file !== '.' && $file !== '..' && $file !== 'img' && $file !== 'tmp') {
  12.  $path =$dir.'/'.$file;
  13.   if (is_dir ($path)) { //si on tombe sur un sous-repertoire
  14.   recursive_readdir ($path); // appel recursif pour lire a l'interieur de ce sous-repertoire
  15. //   echo '<p>[', $path, ']</p>';  
  16.   }
  17.  else // si il s'agit d'un fichier
  18.  // On cherche si $path contient un ou des mp3s
  19.   $pos = strrpos($path, '.');
  20.     if($pos===false)
  21.       { continue;
  22.       } else {
  23.         $good = substr($path, $pos+1);
  24.       }
  25.    
  26.     if ($good == 'mp3') {
  27. //     echo '<p>Ya des mp3 dans ', $dir, ' !</p>';
  28.     $goodList[$goodDir] = $dir;
  29. //     echo $goodList[1];
  30.     }
  31.  }
  32. }
  33. closedir ($dh); // on ferme le repertoire courant
  34. }


(Inspiré de http://www.phpcs.com/codes/PARCOURS-RECURSIF-REPERTOIRE_31179.aspx)
 
Et alors, voyez comme la vie peut être taquine, je *perd* "$goodList" dés que je sors de la fonction, et même AVANT, dés que je sors du while ! L'idée de cette fonction c'est de pouvoir :
 
$newArray=array_unique($goodList);  
Print_R($newArray);  
 
Mais à moins de mettre ça DANS le while, pas moyen. Ma question :
Comment récuperer ce :!çà)('"! de tableau "$newArray" hors de la fonction ??
 
Merci de votre patience
 
Philippe


Message édité par xaccrocheur le 09-09-2008 à 14:12:55
Reply

Marsh Posté le 09-09-2008 à 14:08:17   

Reply

Marsh Posté le 09-09-2008 à 14:11:12    

Faut juste faire un return $goodlist après le close dir, puis le récupérer :

Code :
  1. function recursive_readdir ($dir) {
  2.   ...
  3.   return $goodList;
  4. }
  5. $list = recursive_readdir('some-dir');

Reply

Marsh Posté le 09-09-2008 à 14:12:03    

Et attention à pas mettre trop de commentaires inutiles, ça sert à rien de documenter l'appel à closedir par exemple :/

Reply

Marsh Posté le 09-09-2008 à 14:44:29    

Merci Florent, de ta réponse ultrarapide :) . Bon, on avance. En fait, je crois que je vais aller m'envoyer de la doc sur les array, car je viens de réaliser que je n'ai *aucune idée* claire de la façon dont ça marche, je veux dire :
 
 - Je suis dans une boucle qui affiche à chaque itération une valeur différente de "$dir"
- On pourrait penser qu'à chacune de ces itérations :
$goodList[] = $dir;
 
Remplirait la liste "$goodList[]" et qu'ensuite, ailleurs dans le script, je pourrai appeler $goodList[-1], $goodList[+1], $goodList[0], joyeusement.
 
Eh ben pas du tout. Je vois souvent des exemples :
$goodList[$goodDir] = $dir;
 
Mais ya un parametre de trop, là. Car si Goodlist est un tableau, et dir la *valeur* d'une variable, alors c'est quoi "goodDir" ?
 
En fait, comment on remplit un tableau à 2d, et comment on affiche une de ses valeurs ? Pendant qu'on est là, comment on fait les bébés ?
 
Ya-t-il un topic qui traite de ces questions de BASE à propos des tableaux ??
 
Merci d'ignorer mon ignorance :)
 
-phil


Message édité par xaccrocheur le 09-09-2008 à 17:39:36
Reply

Marsh Posté le 09-09-2008 à 14:58:45    

En fait je dirais que la bonne question est : comment ça marche les fonctions récursives?
 
En fait, t'as l'impression que les variables continuent d'exister tant que tu rapelle la même fonction mais c'est faux. Chaque fois que tu exécutes la fonction "recursive_readdir", elle repart avec un nouvel exemplaire de ces variables.
La variable $goodList du dossier "/" n'est donc pas la même variable que la variable $goodList du dossier "/plop/". Il faut donc que la fonction fasse suivre ce qu'elle a trouvé sinon ça ne sert à rien. C'est à ça (et à la récupération finale) que sert le "return $goodList;" de FlorentG .
 
Le "recursive_readdir ($path);" doit pour sa part être remplacé par du code tel que :

Code :
  1. $SubDir = recursive_readdir ($path);
  2. $goodList = array_merge($goodList, $SubDir);

ou tout autre code php équivalent.
 
 
EDIT : correction de la balise code.


Message édité par omega2 le 09-09-2008 à 15:10:45
Reply

Marsh Posté le 09-09-2008 à 15:08:56    

Merci les gars, C tout à fait le genre d'éclairage que je souhaitais. Je vais m'attaquer mettre en œuvre vos patientes explications.  :jap:

Reply

Marsh Posté le 09-09-2008 à 17:31:18    

Bon, j'ai un peu de mal,  mais ça va rentrer. Ce code :
 

Code :
  1. function recursive_readdir ($dir) {
  2. $goodList = array();
  3. $tempList = array();
  4. $dir = rtrim ($dir, '/'); // on vire un eventuel slash  
  5. if (is_dir ($dir)) // si c'est un repertoire
  6.  $dh = opendir ($dir);
  7. else {
  8.  echo $dir, ' n\'est pas un repertoire valide'; // sinon on sort! Appel de fonction non valide
  9. exit;
  10. }
  11. while (($file = readdir ($dh)) !== false ) {
  12.  if ($file !== '.' && $file !== '..' && $file !== 'img' && $file !== 'tmp') {
  13.  $path =$dir.'/'.$file;
  14.   if (is_dir ($path)) { //si on tombe sur un sous-repertoire
  15.     recursive_readdir ($path); // appel recursif  
  16.     }
  17.   else // si il s'agit d'un fichier
  18.    $pos = strrpos($file, '.');
  19.      if($pos===false)
  20.        { continue;
  21.        } else {
  22.          $good = substr($file, $pos+1);
  23.        }
  24.        // On cherche si l'extention est "mp3"
  25.      if ($good == 'mp3') {
  26.      // echo '<p>Ya des mp3 dans ', $dir, ' !</p>';
  27.      $tempList[] = $dir; // Construction de la liste
  28.      }
  29.  }
  30. }
  31. closedir ($dh);
  32. $goodList = array_unique($tempList);
  33. Print_R($goodList);
  34. // return $goodList;
  35. }
  36. recursive_readdir('.');


 
Produit la sortie suivante :
 
Array ( [0] => ./elephant/elephant_in_paris ) Array ( ) Array ( [0] => ./azero/demos ) Array ( [0] => ./azero/counternatures ) Array ( ) Array ( [0] => ./les_intouchables/now ) Array ( [0] => ./les_intouchables/demos_enfer ) Array ( [0] => ./les_intouchables/touche ) Array ( [0] => ./les_intouchables/tamuziga ) Array ( ) Array ( )
 
... Deux fois. Observations :
 
1 - Ça fait le boulot que je lui demande : Lister les répertoires contenant des fichiers mp3.
2 - Ça fait ce boulot une fois par niveau d'arborescence. Bon, comment n'obtenir qu'un sortie, la dernière, une fois qu'on a bien tout récursé ?)
3 - Print_R me sort ça [0] => ./elephant/elephant_in_paris, toujours [0] Donc en fait, il s'agit d'un tableau de tableaux contenant chacun juste une référence (0, pas 1 ? Bon) Mais j'arrive PAS à piger où se crée cette itération en trop  :cry:  
4 - J'ai bien compris qu'à chaque récursion, les valeurs étaient ré-initialisées, d'où l'utilité de les stocker dans un tableau... Mais comment utiliser le "return" correctement ? Au final, je voudrais "juste" récupérer un tableau que je pourrai "cycler" comment ça :
 
Répertoire précédent : $goodList[-1]
Répertoire courant : $goodList[1]
Répertoire suivant : $goodList[+1]


Message édité par xaccrocheur le 09-09-2008 à 17:41:45
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed