Récursivité et spl

Résolu
bj33 Messages postés 145 Date d'inscription vendredi 13 juin 2003 Statut Membre Dernière intervention 1 mai 2012 - 6 oct. 2010 à 01:30
bj33 Messages postés 145 Date d'inscription vendredi 13 juin 2003 Statut Membre Dernière intervention 1 mai 2012 - 7 oct. 2010 à 01:33
salut,

Pourquoi cette classe n'est pas récursive? Elle ne renvoie que les premiers sous-dossiers sans entrée dans les autres. Qui peut m'aider? Le code :

class FiltreRecursif extends RecursiveFilterIterator {
private $_chemin;
private $_iterateur = NULL;
private $_tabExt = array();
private $_tab = array();
        const NON_VALIDE = 'Chemin incorrect!';
        const NON_TABLEAU = 'Le paramètre n\'est pas un tableau';
      	
function __construct($chemin) {
if (is_dir($chemin))
$this->_chemin = $chemin;
else throw new Exception(SELF::NON_VALIDE);

parent::__construct(new RecursiveDirectoryIterator($this->_chemin,RecursiveDirectoryIterator::CURRENT_AS_SELF));
}

public function getTab() {
return $this->_tab;
}

public function setTabExt($_tabExt) {
if (is_array($_tabExt))
$this->_tabExt = $_tabExt;
else throw new Exception(SELF::NON_TABLEAU);
}

public function accept() {
return $this->hasChildren() || in_array(pathinfo($this->current(),PATHINFO_EXTENSION),$this->_tabExt);
}

public function getChildren() {
return new self($this->getInnerIterator()->current());
}
}


appelée comme ceci :

include_once 'classes/scanne/FiltreRecursif.php';
 try {
$filtre = new FiltreRecursif('tablatures');
$filtre->setTabExt(array('gtp','gp3','gp4','gp5','zip','ptb','tef','pdf'));
foreach ($filtre as $v) {
echo $v->current().'
';
}
 } 
 catch (Format_Generique $e) {
echo $e->toString();
 }


ils ne savaient pas que c'était impossible, alors ils l'on fait. mon modeste site

5 réponses

neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
6 oct. 2010 à 11:24
Salut,

Je suis bien content que de plus en plus de personnes s'intéressent à la SPL... PHP5 est bel et bien là, on commence juste à le sentir...

Concernant la récursivité, c'est un sujet délicat assez difficile à appréhender. De même que les filtres...

Dans ma source XDir, je n'ai pas procédé comme ça, pour parcourir récursivement un répertoire et y appliquer des filtres : j'ai beaucoup plus de classes que toi... Je t'invite à y jeter un oeil pour voir la différence entre nos deux manières de procéder.

Le truc, c'est que FilterIterator n'itère pas vraiment... Il est juste capable de demander les enfants pendant une itération récursive.

Essaie un truc comme ça (ça fonctionne chez moi ;) ) :
try {
$filtre = new recursiveIteratorIterator(new FiltreRecursif('tablatures'));
$filtre->setTabExt(array('gtp','gp3','gp4','gp5','zip','ptb','tef','pdf'));
foreach ($filtre as $v) {
echo $v->current().'
';
}
 } 
 catch (Format_Generique $e) {
echo $e->toString();
 }


En réalité, c'est recursiveIteratorIterator qui va itérer récursivement. Il prend en argument un itérateur récursif qui est une instance de RecursiveIterator : cette interface est la seule qui permette de spécifier à PHP qu'il y a une itération récursive (et de l'exécuter grâce aux méthodes getChildren() et hasChildren()). Je sais pas si c'est bien clair mon blabla...

--
Neige

Souvent la réponse à votre question se trouve dans la doc. Commencez par là ;)
3
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
6 oct. 2010 à 11:26
Ah ! J'ai oublié un truc !

SELF est une constante qui n'est pas définie dans ton code... Le mot clé qui fait référence à la classe en statique est self, en minuscules. Utiliser SELF en majuscules provoque une erreur ;)

--
Neige

Souvent la réponse à votre question se trouve dans la doc. Commencez par là ;)
0
bj33 Messages postés 145 Date d'inscription vendredi 13 juin 2003 Statut Membre Dernière intervention 1 mai 2012
7 oct. 2010 à 00:16
salut neigedhiver

<< Je suis bien content que de plus en plus de personnes s'intéressent à la SPL...

Ce n'est par encore çà et je le comprend, il manque cruellement de docs même en anglais, complète j'entends, avec des exemples concrets. J'ai testé ta solution bien avant que tu me là propose, celle de malalam aussi. Bien évidement, c'est plaisant et flexible mais pour comprendre cette foutue récursivité via la spl j'ai eu besoin de réinventer la roue. Quoi que l'on puisse en dire, c'est puissant mais demande un réel investissement, pas simple de comprendre l'imbrication de tout les objets/interfaces mis en oeuvre. En fait, c'est le blog de julien pauli qui m'à fait comprendre la puissance de la spl et finalement sa simplicité relative. Tout n'est aussi corsé que la récursivité quand on veux appliquer des filtres. Heureusement! Et c'est tant mieux

<< SELF est une constante qui n'est pas...

Désolé, il était tard. Il y en à même une autre, le double soulignement de toString, il était vraiment tard:) Les constantes proviennent d'une classe abstraite et les erreurs sont gérées par une classe qui étend Exception, j'ai mal simplifié.

<< Je sais pas si c'est bien clair mon blabla...

Très! D'ailleurs, çà fonctionne maintenant mais j'ai bien failli retourner à opendir...Pour ceux qui seraient dans mon cas et qui arriveraient içi par le biais d'un moteur, un squelette qui fonctionne. getChildren était mal surchargée.

class Recursif extends RecursiveFilterIterator {
    private $_Iterateur;
    private $_TabExtensions = array();


    function  __construct(RecursiveIterator $iterateur, array $tab_extensions) {
        $this->_Iterateur = $iterateur;
        $this->_TabExtensions = $tab_extensions;
        parent::__construct($this->_Iterateur);
    }

    function  accept() {
        return $this->hasChildren() || in_array(pathinfo($this->current(), PATHINFO_EXTENSION), $this->_TabExtensions);
    }
    
    function  getChildren() {
        return new self($this->getInnerIterator()->getChildren(), $this->_TabExtensions);
    }
}

 try {
 	
 	$filtre = new RecursiveDirectoryIterator('le dossier');
$filtres = new Recursif($filtre,array('php','php5','css','htm','html','js'));
foreach (new RecursiveIteratorIterator($filtres,RecursiveIteratorIterator::SELF_FIRST) as $v) {
echo $v.'
';
}
 } 
 catch (Exception $e) {
echo $e->__toString();
 }


Y à plus qu'à nettoyer,formatter,afficher... Merci neigedhiver. Certes, ce n'est pas aussi flexible que XDir mais çà và à l'essentiel. Et c'est ce dont j'ai besoin. une classe php5 véritable, utilisable dans tout les projets et spécialisée.


ils ne savaient pas que c'était impossible, alors ils l'on fait. mon modeste site
0
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
7 oct. 2010 à 00:30
Je suis d'accord avec toi au sujet des docs sur la SPL.
J'ai déjà trouvé les articles de Julien Pauli sur developpez.com, mais j'avoue que je suis perplexe quant à sa manière d'utiliser les exceptions. A tel point que je prévois (bon ok, ça fait un moment maintenant, mais je pense que je vais vraiment m'y coller prochainement) de faire un vrai tuto sur les exceptions : qu'est-ce que c'est vraiment une exception, pourquoi s'en servir, comment s'en servir, lesquelles utiliser et quand...

Ma source XDir, je l'aime, j'en suis assez fier (c'est ma chouchoutte, mais faut pas le dire, hein...). Elle est loin d'être parfaite, notamment, elle est trop lourde (mais c'est le risque quand on fait un package complet plutôt que du sur mesure) et elle a encore un bug que j'aimerais pouvoir solutionner (la suppression d'un répertoire, point soulevé en commentaire). Je l'ai voulue simple à utiliser. Et je me suis arraché pas mal de cheveux pour y parvenir, parce que j'ai été confronté à ce problème de filtres très rapidement ; c'est ce qui explique toutes ces classes... Et quand j'ai lu ton message, j'ai mis du temps à percuter vraiment ce qui clochait, avant de me souvenir que c'était RecursiveIteratorIterator. Le seul petit "défaut" de ton code, à mon avis, tel qu'il est là, c'est la (relative) complexité pour faire une itération. Ta boucle foreach me semble un peu... complexe. Entends par là, pas facilement lisible. L'intérêt de tout encapsuler dans des classes, c'est que cette partie du travail ne sera plus à refaire : après tout, on n'en a pas besoin pour lire le code, celui d'une classe ne doit pas être utile pour lire le code du programme, la classe ne devant être qu'une bibliothèque (c'est mon point de vue et je le partage).

Sinon, je ne peux que saluer ton initiative à réinventer la roue : c'est comme ça qu'on apprend. Evidemment, si tu postes une source qui serait un clone de XDir, je trouverais ça inutile (et mesquin, mais c'est très personnel et subjectif lol). Et je salue également le fait que tu aies posté la solution complète dans le fil pour les recherches ultérieures d'autres dans le besoin (parce que l'air de rien, phpcs est super bien référencé).

Voilà, j'arrête mon baratin...

--
Neige

Souvent la réponse à votre question se trouve dans la doc. Commencez par là ;)
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
bj33 Messages postés 145 Date d'inscription vendredi 13 juin 2003 Statut Membre Dernière intervention 1 mai 2012
7 oct. 2010 à 01:33
<< L'intérêt de tout encapsuler dans des classes, c'est que cette partie du travail ne sera plus à refaire

Tout à fait d'accord, c'est un squelette. Je vais voir maintenant comment le développé. Rassure toi, c'est purement personnel, instructif ;) Je n'ai pas ton niveau et j'ai une autre idée.

<< je suis perplexe quant à sa manière d'utiliser les exceptions

çà reste quand même un cador du genre et tout ces exemples sont de qualités, son tutoriel sur le pattern observer est plutôt superbe et on trouve sur son blog des exemples didactiques sur la spl, pour l'instant sans égal en francais et j'ai cherché.

Merci encore pour l'aiguillage et à bientôt(?) pour le tuto sur les exceptions.

ils ne savaient pas que c'était impossible, alors ils l'on fait. mon modeste site
0
Rejoignez-nous