IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

[SPL] Utilisation de RecursiveIterator [PHP 5.2]


Sujet :

Langage PHP

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Août 2007
    Messages
    21
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France, Doubs (Franche Comté)

    Informations forums :
    Inscription : Août 2007
    Messages : 21
    Points : 25
    Points
    25
    Par défaut [SPL] Utilisation de RecursiveIterator
    Bonjour.

    J'ai un petit soucis avec la SPL et RecursiveIteratorIterator.
    Voici ma classe:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
     
    class Group_Container implements RecursiveIterator
    {
        protected $_elems;
     
        public function __construct()    { $this->_elems=array(); }
     
    // implements Iterator:
        public function current()    {        return current($this->_elems);    }
        public function key()    {        return key($this->_elems);    }
        public function next()    {        return next($this->_elems);    }
        public function rewind()    {        reset($this->_elems);    }
        public function valid()    {        return array_key_exists($this->key(), $this->_elems);    }
     
    // implements RecursiveIterator:
        public function hasChildren()    {
            return ($this->current() instanceof Group_Container);
        }
        public function getChildren()    {
            return new RecursiveIteratorIterator($this->current());
        }
     
    // implements standart OOP:
        public function __set($key, $val)    {
            $this->_elems[$key]=$val;
            return $this;
        }
        public function __get($key)    {
            if ($this->__isset($key)) {
                return $this->_elems[$key];
            } else {
                throw new Exception("element $key inexistant");
            }
        }
        public function __isset($key)    {
            return isset($this->_elems[$key]);
        }
        public function __unset($key)    {
            if ($this->__isset($key)) {
                unset($this->_elems[$key]);
                return $this;
            } else {
                throw new Exception("element $key inexistant");
            }
        }
    }
    Ensuite, je crée un objet group, qui contient un string et un autre group qui contient un autre string:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    $group=new Group_Container();
    $group->elem1="elem1";
     
    $group2=new Group_Container();
    $group2->elem1="group2.elem1";
     
    $group->group2=$group2;
    Jusque là tout va bien. Maintenant pour browser mon objet, si je le fais en utilisant un simple Iterator:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    foreach ($group as $key=>$val) {
        if ($val instanceof Group_Container) {
            foreach ($val as $key=>$val) {
                echo "$key: ".print_r($val,true)."\n";
            }
        } else {
            echo "$key: ".print_r($val,true)."\n";
        }
    }
    Ca m'affiche cela: (normal)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    elem1: elem1
    elem1: group2.elem1
    Maintenant, ce code est bien beau, mais est limité à une seule profondeur. Si je veux utiliser RecursiveIterator, je devrais faire comme celà:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    foreach (new RecursiveIteratorIterator($group) as $key=>$val) {
            echo "$key: ".print_r($val,true)."\n";
    }
    Ce qui devrait me donner le même résultat, mais sans la limitation de la profondeur limité à 1.

    Or, cela me sort ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    elem1: elem1
    Fatal error:  Uncaught exception 'UnexpectedValueException' with message 'Objects returned by RecursiveIterator::getChildren() must implement RecursiveIterator' in test.php:58
    Stack trace:
    #0 test.php(58): unknown()
    #1 {main}
      thrown in test.php on line 58
    Maintenant, getChildren est appelé si hasChildren() renvoit true. Donc lorsque $this->current est une instance de Group_Container. (j'ai vérifié en faisant un print_r($this->current). Donc Group_Container implémente bien RecursiveIterator.
    D'ailleurs, j'utilise new RecursiveIteratorIterator(objet) dans mon foreach.

    Bref, je ne comprends pas, là ...

    Une idée ?

  2. #2
    Expert éminent sénior
    Avatar de mathieu
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    10 393
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 10 393
    Points : 15 754
    Points
    15 754
    Par défaut
    des fois il y a "RecursiveIterator" et à d'autres endroits dans ton code il y a "RecursiveIteratorIterator" ce n'est pas là le problème ?

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Août 2007
    Messages
    21
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France, Doubs (Franche Comté)

    Informations forums :
    Inscription : Août 2007
    Messages : 21
    Points : 25
    Points
    25
    Par défaut
    Non, je ne crois pas.
    RecursiveIterator est une interface, et RecursiveIteratorIterator est une classe, qui prend comme argument dans son constructeur une classe qui implémente RecursiveIterator.
    Merci de la suggestion quand même !

  4. #4
    Expert éminent sénior
    Avatar de mathieu
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    10 393
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 10 393
    Points : 15 754
    Points
    15 754
    Par défaut
    le problème est que "getChildren" doit retourner un objet qui implémente "RecursiveIterator" :
    http://php.net/~helly/php/ext/spl/in...ef690f4ce6bb90

    et donc il y a une erreur puisque "RecursiveIteratorIterator" n'implémente pas "RecursiveIterator" :
    http://php.net/~helly/php/ext/spl/cl...rIterator.html

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Août 2007
    Messages
    21
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France, Doubs (Franche Comté)

    Informations forums :
    Inscription : Août 2007
    Messages : 21
    Points : 25
    Points
    25
    Par défaut
    Bien vu !

    Il faut donc que je change
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        public function getChildren()    {
            return new RecursiveIteratorIterator($this->current());
        }
    en:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        public function getChildren()    {
            return $this->current();
        }
    Et ca fonctionne !

    En fait la classe RecursiveIteratorIterator appelle elle-même new RecursiveIteratorIterator($objet) après getChildren(). Il ne fallait pas le faire à sa place.
    Merci du coup de pouce, Mathieu !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 07/12/2011, 12h39
  2. SPL et RecursiveIterator
    Par Mr N. dans le forum Langage
    Réponses: 0
    Dernier message: 18/03/2010, 02h23
  3. [Librairies] qui utilise la SPL ?
    Par kerzut dans le forum Bibliothèques et frameworks
    Réponses: 3
    Dernier message: 01/12/2005, 21h46
  4. Réponses: 2
    Dernier message: 20/03/2002, 23h01

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo