Reputation: 125
Is there a way to iterate over an object's keys implementing ArrayAccess and Iterator interfaces? Array access works as a charm but I can't use foreach on those objects which would help me a lot. Is it possible? I have such code so far:
<?php
class IteratorTest implements ArrayAccess, Iterator {
private $pointer = 0;
public function offsetExists($index) {
return isset($this->objects[$index]);
}
public function offsetGet($index) {
return $this->objects[$index];
}
public function offsetSet($index, $newValue) {
$this->objects[$index] = $newValue;
}
public function offsetUnset($index) {
unset($this->objects[$index]);
}
public function key() {
return $this->pointer;
}
public function current() {
return $this->objects[$this -> pointer];
}
public function next() {
$this->pointer++;
}
public function rewind() {
$this->pointer = 0;
}
public function seek($position) {
$this->pointer = $position;
}
public function valid() {
return isset($this->objects[$this -> pointer]);
}
}
$it = new IteratorTest();
$it['one'] = 1;
$it['two'] = 2;
foreach ($it as $k => $v) {
echo "$k: $v\n";
}
// expected result:
// one: 1
// two: 2
Thanks for any help and hints.
Upvotes: 2
Views: 6236
Reputation: 645
I use this to implement Iterator
. Maybe you can adapt it to your code ;)
class ModelList implements Iterator {
public $list;
private $index = 0;
public $nb;
public $nbTotal;
public function __construct() {
$this->list = [];
$this->nb = 0;
$this->nbTotal = 0;
return $this;
}
/**
* list navigation
*/
public function rewind() {
$this->index = 0;
}
public function current() {
$k = array_keys( $this->list );
$var = $this->list[ $k[ $this->index ] ];
return $var;
}
public function key() {
$k = array_keys( $this->list );
$var = $k[ $this->index ];
return $var;
}
public function next() {
$k = array_keys( $this->list );
if ( isset( $k[ ++$this->index ] ) ) {
$var = $this->list[ $k[ $this->index ] ];
return $var;
} else {
return false;
}
}
public function valid() {
$k = array_keys( $this->list );
$var = isset( $k[ $this->index ] );
return $var;
}
}
Upvotes: 3
Reputation: 14959
while ($it->valid()) {
echo $it->key().' '.$it->current();
$it->next();
}
Would be my approach, however, this function looks iffy:
public function next() {
$this->pointer++;
}
Incrementing 'one' isn't likely to give you 'two'. Try the code in the answers to this question to get the next array key:
$keys = array_keys($this->objects);
$position = array_search($this->key(), $keys);
if (isset($keys[$position + 1])) {
$this->pointer = $keys[$position + 1];
} else {
$this->pointer = false;
}
Upvotes: 2