Reputation: 67703
I have an object that implements ArrayAccess, Iterator and Countable. That produces a nigh-perfect array masking. I can access it with offsets ($object[foo]
), I can throw it into a foreach
-loop, and many other things.
But what I can't do is give it to the native array iterator functions (next()
, reset()
, current()
, key()
), even though I have implemented the required methods from Iterator. PHP seems to stubbornly try to iterate through its member variables, and entirely disregards the iterator-methods.
Is there an interface that would hook the object to the remaining array-traversing-functions, or am I stuck with what I have?
Update: IteratorAggregate doesn't seem to be the answer either. While it is used in foreach
-loops, the basic array iterator functions don't call the methods.
Upvotes: 1
Views: 614
Reputation: 3359
Recent changes in PHP prevent ArrayIterators form being manipulated using the standard array functions (reset, next, etc).
This should be restored soon: http://news.php.net/php.internals/42015
Upvotes: 5
Reputation: 13379
One way to get this to work is to define your own iterator in a separate class, and then tell your main class to use that new iterator instead of the default one.
class MyIterator implements Iterator {
public function key() {
//
}
public function rewind() {
//
}
// etc.
}
class MyMainClass implements IteratorAggregate {
private $_data = array();
// getIterator is required for the IteratorAggregate interface.
public function getIterator() {
return new MyIterator($this->_data);
}
// etc.
}
Then you should have as much control as you need. (And you can reuse your own MyIterator across a number of classes).
No testing done on the above, but the principle is correct, I believe.
Hope this helps!
Upvotes: 3
Reputation: 105878
Is ArrayIterator not what you're looking for? Or what about ArrayObject, which seems to be SPL's interface for what you're trying to achieve.
Upvotes: 0