Iterator
Aus php bar
Bei Iteratoren handelt es sich um eine Technik aus dem Bereich der funktionalen Programmierung. Mit Hilfe von Iteratoren ist es möglich, mit foreach eine Liste von Elementen abzuarbeiten.
Inhaltsverzeichnis |
PHP 4
Mit PHP 4 kann man nur über Eigenschaften eines Objektes iterieren:
1 class Foo 2 { 3 var $a = 1; 4 var $b = 2; 5 var $c = 3; 6 } 7 8 $foo = new Foo(); 9 10 foreach ($foo AS $name => $wert) 11 { 12 echo "$name: $wert\n"; 13 }
Gibt folgendes aus:
a: 1 b: 2 c: 3
PHP 5
Mit PHP 5 hat Marcus Börger ein erweitertes Iterator-Interface für PHP implementiert. Nun ist es möglich, die Iteration aus dem Objekt heraus zu steuern. Um ein Objekt iterierbar zu machen, muss das Interface Iterator implementiert werden, damit die Engine weiß, dass sie nicht über die Eigenschaften iterieren soll. Dabei ist es, wie bei jedem anderen Interface auch, nötig, die definierten Methoden zu implementieren.
Bei Iteratoren gibt es für die einzelnen Schritte eines foreach je eine Methode, die aufgerufen wird: Zunächst wird der Datensatzzeiger auf das erste Element gesetzt (rewind()). Dann wird für jedes Element der Wert (current()) und der Schlüssel (key()) ausgelesen. Es wird geschaut, ob es weitere Elemente gibt, (valid()) und wenn möglich der Datensatzzeiger auf das nächste Element verschoben (next()).
Eigene Iteratoren
Um eine Klasse iterierbar zu machen, muss man einfach das Iterator-Interface implementieren. Eine einfache Implementierung könnte so aussehen:
1 class MeineKlasse implements Iterator { 2 private $satzzeiger = 0; 3 4 public function rewind() { 5 $this->satzzeiger = 0; 6 } 7 8 public function key() { 9 return $this->satzzeiger; 10 } 11 12 public function current() { 13 switch ($this->satzzeiger) { 14 case 0: 15 return 'Hund'; 16 case 1: 17 return 'Katze'; 18 case 2: 19 return 'Maus'; 20 } 21 22 return false; 23 // throw new Exception('Invalid ke'); wäre schöner, geht zur Zeit nicht, ist aber ein reporteter Bug... 24 } 25 26 public function valid() { 27 return $this->satzzeiger < 3; 28 } 29 30 public function next() { 31 $this->satzzeiger++; 32 } 33 } 34 35 $objekt = new MeineKlasse(); 36 foreach ($objekt AS $schluessel => $wert) { 37 echo "$schluessel: $wert\n"; 38 }
Dieses Skript erzeugt folgende Ausgabe:
0: Hund 1: Katze 2: Maus
Iteratoren in PHP5 Extensions
Neben eigenen Iteratoren kann man auch welche nutzen, die von verschiedenen Extensions zu Verfügung gestellt werden. Zum einen gibt es verschiedene PHP-Klassen, die Iteratoren anbieten, zum anderen Interfaces, die erweiterte Iterator-Schnittstellen nutzbar machen.
SQLite
Die SQLite Datenbank-Extension bietet Iteratoren, um über die Ergebnisse einer Abfrage zu iterieren:
1 $sqlite = new SQLiteDatabase($database_datei); 2 $query = $sqlite->query('SELECT foo FROM bar'); 3 foreach ($query AS $result) { 4 echo $result['foo']; 5 }
SPL (Standard PHP Library)
Die SPL-Extension bietet u.a. auch einige erweiterte Iterator-Interfaces und -Klassen an. So ist es auf einfache Weise möglich, mit Hilfe des, aus dem RecursiveIterator und DirectoryIterator (beide ebenfalls Teil von SPL) zusammengesetzten RecursiveDirectoryIterator mit wenigen Zeilen PHP-Code ein Verzeichnis rekursiv, Datei für Datei, abzuarbeiten. Beipiele dazu finden sich auf dem PHP-CVS-Server.

