Yes, you can.
foreach(new IteratorOne($obj) as $foo) .... foreach(new IteratorTwo($obj) as $bar) .....
Actually, as long as you implement the Iterator class, you can apply any arbitrary IteratorIterator to it. This is a good thing, because application metarators are not required to know anything about the class in question.
Consider, for example, an iterable class like this
class JustList implements Iterator { function __construct() { $this->items = func_get_args(); } function rewind() { return reset($this->items); } function current() { return current($this->items); } function key() { return key($this->items); } function next() { return next($this->items); } function valid() { return key($this->items) !== null; } }
Let us define some metarator
class OddIterator extends FilterIterator { function accept() { return parent::current() % 2; } } class EvenIterator extends FilterIterator { function accept() { return parent::current() % 2 == 0; } }
Now apply the metatherators to the base class:
$list = new JustList(1, 2, 3, 4, 5, 6, 7, 8, 9); foreach(new OddIterator($list) as $p) echo $p;
UPDATE: php has no inner classes, so you are out of luck here without resorting to eval, at least. Your iterators should be separate classes that are aware of the structure of the base layer. You can make this less harmful by providing methods in the base class that instantiate iterators behind the scenes:
class TreeDepthFirstIterator implements Iterator { function __construct($someTree)..... } class Tree { function depthFirst() { return new TreeDepthFirstIterator($this); } .... } foreach($myTree->depthFirst() as $node).....
Another option is to use lambdas instead of foreach. This is better and more flexible, but requires php5.3:
class Tree { function depthFirst($func) { while($node = .....) $func($node); ..... $myTree->depthFirst(function($node) { echo $node->name; });