Es ist ein Model und es sieht gut aus – Iterator

Nachdem sich unsere Klasse Custom_Model während der letzten Artikel gut entwickelt hat, werden wir daran heute gleich anknüpfen und das Iterator-Interface implementieren.

Was kann unser Model dann, was es vorher noch nicht konnte? Durch die Verwendung des Interfaces können wir die gespeicherten Daten in einer foreach-Schleife verarbeiten. Das kann z.B. beim erzeugen von Tabellen erforderlich sein.

Wie immer beginne ich mit einer Skizze der heutigen Erweiterungen.

<?php
interface Custom_Model_Interface
  extends ArrayAccess,
          Iterator,
          Countable
{
}

Unser Interface Custom_Model_Interface erweitert zunächst das Iterator-Interface und auch Countable. Dadurch lassen sich dann die Elemente des Objektes zählen und in Verbindung mit ArrayAccess auch beliebig in einer for-Schleife verarbeiten.

In unserer Klasse müssen wir nun die entsprechenden Methoden deklarieren.

<?php
class Custom_Model implements Custom_Model_Interface
{
  // ...

  public function current() {}
  public function key() {}
  public function next() {}
  public function rewind() {}
  public function valid() {}
  public function count() {}

// ...
}

Jedem, der lange genug mit PHP arbeitet sollte nun was auffallen. Richtig! Wir halten unsere “Feldnamen” in einem Array und zu fast jeder Methode gibt es eine gleichnamige Array-Funktion.

Da wir aber an meistens an die Werte und nicht an die Namen der Felder wollen, müssen wir etwas tricksen.

Die erste Methode current() gibt das jeweilige Element an der Position des internen Zeigers zurück und entspricht damit der gleichnamigen Array-Funktion current().

public function current()
{
  return $this->_get(current($this->_keys));
}

Das Gegenstück dazu stellt quasi key() dar, da es den Feldnamen der Position liefert.

public function key()
{
  return $this->_keys[key($this->_keys)];
}

Auf den ersten Blick mag diese Schreibweise vielleicht etwas verwirren, aber nur so bekommen wir den richtigen Schlüssel. key() gibt uns den aktuellen Schlüssel von $this->_keys zurück, wir wollen den Wert der jeweiligen Position haben.

Um nun in der Schleife den internen Zeiger bewegen zu können, brauchen wir next().

public function next()
{
  next($this->_keys);
}

Wird das Objekt ein weiteres Mal mit foreach verarbeitet, so muss der interne Zeiger wieder auf die erste Position zurückgesetzt werden. Das Iterator-Interface schreibt dafür die Methode rewind() vor, die dann intern reset() verwenden kann.

public function rewind()
{
  reset($this->_keys);
}

Innerhalb der Schleife wir überprüft, ob weitere Elemente vorhanden sind. Dazu wird valid() verwendet.

public function valid()
{
  return current($this->_keys) !== false;
}

Damit haben wir alles notwendige eingebaut, damit unser Model in einer foreach-Schleife ausgelesen werden kann.

foreach($model as $key=>$value) {
  echo $key . ' = ' . $value . '<br/>';
}

Zuletzt gibt es dann auch noch die Methode count() des Countable-Interfaces, damit wir beliebig mit for-Schleifen über das Objekt iterieren können.

public function count()
{
  return count($this->_keys);    
}

und

for($i=0; $i<count($model); $i++) {
  echo $i . ' = ' . $model[$i] . '<br/>';
}

Damit wären wir auch schon wieder am Ende. Beim nächsten Mal geht es dann weiter mit dem Observer-Pattern.

Schlagwörter: Adapter, Amazon, Animation, Annotations, Anonyme Klasse, Ant, Apache, API, Array, ArrayAccess, Attachment, AutoLoader, Bedienung, Bedingung, Benchmark, Bildbearbeitung, BOM, Bootstrap, Bot, Byte Order Mark, Callback, CamelCase, Canvas, Captcha, Cheatsheet, CLI, Closure, Cloud, CodeSniffer, Community, Comparator, Contest, Controller, Converter, CouchDB, Countable, Cronjob, CSV, CustomLibrary, Custom_Model, Data Mapper, Datei, Datenbank, Datenstruktur, Datentypen, Dating, Decorator, Dekorierer, Design Patterns, Dump, Duplikat, each, Eclipse, Entwicklung, Entwurfsmuster, Enum, Erweiterung, Eventhandling, Exception-Handling, Extension, Factory, Fehler, Flash, Foreach, Formatierung, Formular, Funktion, Futon, Header, HTML5, HTTP, IDE, If, Implementierung, InnoDB, Interceptor, Interface, isset, Iterator, Java, JavaScript, jQuery, Konfiguration, Konsole, Kontrollstruktur, kopieren, Late Static Binding, Layout, Linux, Listeners, Logging, Löschen, Magento, Magic Methods, Marketing, Methode, Model, MVC, MySQL, NetBeans, Objekt, Observable, Observer, OOP, Operator, Parameter, Partnersuche, Performance, PHP, phpMyAdmin, PHPUnit, Plugin, Proxy, Qualitätssicherung, Query, Reflection, Request, Response, Rest-API, Rockstar, Routing, S3, Samba, Scheifen, Schleife, Schutz, Secure Shell, Selbstreferenz, Shop, Sicherheit, Sicherung, Singleton Pattern, SOAP, Sortierung, Sourcecode, Spam, Speicherproblem, Spickzettel, SPL, SSH, Statement, Stellvertreter, Strategy Pattern, Stream, String, Sun VirtualBox, Support, Switch, Symfony, Symfony2, Symfony Live, Tag, Template, Template Method, Ternär Operator, Testing, Thumbnail, Tool, Tour, Twig, Type-Cast, Umwandlung, Underscore, unset, Vererbung, Verzweigung, Video, Videospiel, Virtualisierung, Visitor Pattern, Vorschaubild, walk, Webserver, Webservice, Weiterleitung, Wrapper, Youtube, Zeitsteuerung, Zend Framework, Zend_Cloud, Zend_CodeGenerator, Zend_Http_Client, Zend_Service, Zugriffsmethode