Henrik Paul
Henrik Paul

Reputation: 67703

PHP objects as faux-arrays

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

Answers (3)

ringmaster
ringmaster

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

majelbstoat
majelbstoat

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

Peter Bailey
Peter Bailey

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

Related Questions