33. Il metodo Magico __call()


Overload di __call()

Prototipo della funzione :

mixed __call (string method, array arguments)

Mediante l'overloading del metodo magico __call(), abbiamo la possibilità di catturare e gestire tutte le chiamate a metodi non esistenti ossia non dichiarati nella classe.

L'overload di questo metodo torna particolarmente utile qualora si utilizzi una strategia di programmazione come la Delegation Pattern.

<?php

	class Oggetto
	{
		private $arr;

		public function Oggetto()
		{
			$this->arr = array();
		}

		private function aggiungiAllaFine($valore)
		{ array_push($this->arr, $valore); }
		
		private function aggiungiAllInizio($valore)
		{ array_unshift($this->arr, $valore); }

		public function __call($metodo, $parametri)
		{
			if ($metodo == "aggiungi")
			{
				if ($parametri[1] == "inizio")
				{ $this->aggiungiAllInizio($parametri[0]); }
				else if ($parametri[1] == "fine")
				{ $this->aggiungiAllaFine($parametri[0]); }
				else
				{ throw new Exception("Parametri non validi"); }
			}
			else
			{ throw new Exception("Metodo inesistente"); }
		}

		public function mostra()
		{
			foreach ($this->arr as $valore)
			{
				echo "$valore<br />\n";
			}
		}
	}

	try
	{
		$obj = new Oggetto();

		$obj->aggiungi(3, "inizio");
		$obj->aggiungi("pippo", "inizio");
		$obj->aggiungi(44.5, "fine");
		$obj->aggiungi("ciao", "inizio");

		$obj->mostra();

		$obj->aggiungi(5);
	}
	catch (Exception $e)
	{ echo $e->getMessage(); }

?>

Il codice produce questo output sul browser :

ciao
pippo
3
44.5
Parametri non validi

Nota : __call() può restituire dei valori proprio come un metodo tradizionale, e come tale può chiamare anche funzioni esterne e metodi di altre classi.

Nell'articolo Wikipedia da me segnalato sulla Delegation Pattern non viene usato __call(), ma viene spiegato semplicemente l'utilizzo di questa strategia di programmazione, a cui potrete poi facilmente applicare l'overload di __call().