IteratorAggregate::getIterator

(PHP 5, PHP 7, PHP 8)

IteratorAggregate::getIteratorRetrieve an external iterator

Descrizione

public IteratorAggregate::getIterator(): Traversable

Returns an external iterator.

Elenco dei parametri

Questa funzione non contiene parametri.

Valori restituiti

An instance of an object implementing Iterator or Traversable

Errori/Eccezioni

Throws an Exception on failure.

add a note add a note

User Contributed Notes 1 note

up
0
thomas at gielfeldt dot dk
9 years ago
Be careful when caching the iterator AND supplying the iterator with a back reference to the IteratorAggregate implementor. This can cause a potential memory leak.

<?php

class MyClass implements IteratorAggregate {
  public
$data;
  protected
$iterator;

  public function
getIterator() {
   
// This is the culprit. Combined with the passing of $this,
    // neither this object nor the iterator will be destroyed until
    // php has finished execution and cleans up.
   
return $this->iterator ? $this->iterator : $this->iterator = new MyIterator($this);
  }

  public function
__construct($data) {
    print
"CONSTRUCTING MyClass!\n";
   
$this->data = $data;
  }

  public function
__destruct() {
    print
"DESTROYING MyClass!\n";
  }
}

class
MyIterator implements Iterator {
  protected
$obj;

  public function
__construct($obj) {
    print
"CONSTRUCTING MyIterator!\n";
   
$this->obj = $obj;
  }

  public function
current() { return current($this->obj->data); }
  public function
key() { return key($this->obj->data); }
  public function
next() { return next($this->obj->data); }
  public function
rewind() { return reset($this->obj->data); }
  public function
valid() { return key($this->obj->data) !== NULL; }

  public function
__destruct() {
    print
"DESTROYING MyIterator!\n";
  }
}

function
test1() {
 
$a = new MyClass(array(1, 2, 3, 4));

  foreach (
$a as $k => $v) {
    print
"$k => $v\n";
  }
  print
"Iteration done!\n";
}

test1();
print
"test1 done\n";

?>

Expected result
--------------------
CONSTRUCTING MyClass!
CONSTRUCTING MyIterator!
0 => 1
1 => 2
2 => 3
3 => 4
DESTROYING MyIterator!
Iteration done!
DESTROYING MyClass!
test1 done

Actual result
--------------------
CONSTRUCTING MyClass!
CONSTRUCTING MyIterator!
0 => 1
1 => 2
2 => 3
3 => 4
Iteration done!
test1 done
DESTROYING MyClass!
DESTROYING MyIterator!
To Top