37. Overload dell'interfaccia di Iterazione

Illustrerò in questo capitolo l'ultimo overload che vedrà come protagonista l'interfaccia nativa Iterator.

Implementando questa interfaccia nelle nostre classi, avremo modo di fornire gli strumenti a PHP per gestire tali oggetti nei cicli di iterazione.

L'overload di questa interfaccia abbinata ad ArrayAccess vi consentirà di costruire degli strumenti veloci e flessibili per interagire più rapidamente con le vostre classi.

Gli indici per effettuare le iterazioni sugli oggetti dovranno essere attributi interni della classe.

Vediamo come è costituita l'interfaccia Iterator :

interface Iterator

  • void rewind()
  • mixed current()
  • mixed key()
  • void next()
  • bool valid()
  • rewind() - Azzera l'indice del ciclo facendolo tornare all'inizio
  • current() - Ritorna il valore della posizione corrente
  • key() - Restituisce l'indice / chiave della posizione corrente
  • next() - Aumenta l'indice per puntare all'elemento successivo
  • valid() - Ritorna true o false per controllare se l'array è finito (viene interrogato prima di una chiamata a current() o key())

Esempio overload Iterator

Per creare un esempio più semplice possibile non ho volutamente utilizzato l'ereditarietà, ma ho creato due semplici classi base.

La prima classe è Unità e rappresenta un unità presente in un magazzino, con il nome, prezzo e codice.

La seconda e ultima classe (Magazzino) è un semplice contenitore di Unità, che memorizzerà utilizzando un array classico monodimensionale, dove l'elemento singolo non sarà un semplice valore ma l'oggetto più complesso Unità.

<?php

	class Unita
	{
		public $nome;
		public $prezzo;
		public $codice;

		public function Unita($n, $p, $c)
		{
			$this->nome = $n;
			$this->prezzo = $p;
			$this->codice = $c;
		}
	}

	class Magazzino implements Iterator
	{
		private $pezzi;
		private $current; // Indice interno per gestire l'iterazione

		public function Magazzino()
		{
			$this->pezzi = array();
		}

		/* Inizio Interfaccia Iterator */
		function rewind()
		{
			$this->current = 0;
		}

		function current()
		{
			return $this->pezzi[$this->current];
		}

		function key()
		{
			return $this->current;
		}

		function next()
		{
			return $this->current++;
		}

		function valid()
		{
			return isset($this->pezzi[$this->current]);
		}
		/* Fine Interfaccia Iterator */

		public function aggiungi(Unita $unita)
		{
			array_push($this->pezzi, $unita);
		}
	}

	$store = new Magazzino();

	$store->aggiungi(new Unita("Le avventure dello zio Pasquale", 15.5, "A096H"));
	$store->aggiungi(new Unita("I delitti di Grottaferrata", 12.0, "B076X"));
	$store->aggiungi(new Unita("Quando dico Basta!!", 23.5, "KJ87F2"));

	foreach ($store as $unita)
	{
		echo "Nome = $unita->nome<br />\n";
		echo "Prezzo = $unita->prezzo<br />\n";
		echo "Codice = $unita->codice<br /><br />\n\n";
	}

?>

Il codice produce il seguente risultato :

Nome = Le avventure dello zio Pasquale
Prezzo = 15.5
Codice = A096H

Nome = I delitti di Grottaferrata
Prezzo = 12
Codice = B076X

Nome = Quando dico Basta!!
Prezzo = 23.5
Codice = KJ87F2