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 ?