[SPL] Utilisation de RecursiveIterator
Bonjour.
J'ai un petit soucis avec la SPL et RecursiveIteratorIterator.
Voici ma classe:
Code:
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:
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:
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:
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:
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:
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 ?