Die Verwendung von __call($methodName, $parameters) bietet
sich beispielsweise an, um ein generisches Stellvertreter-Objekt
(siehe „Stellvertreter“) zu
implementieren, das anstelle eines anderen Objektes verwendet werden
kann. So implementiert die Klasse Cache
(Beispiel 2.6) einen
Mechanismus für das Vorhalten von bereits berechneten Ergebnissen von
Methoden beliebiger anderer Klassen.
Beispiel 2.6: Die Klasse Cache
<?php
class Cache {
protected $cache = array();
protected $object;
public function __construct($object) {
$this->object = $object;
}
public function __call($methodName, $parameters) {
$id = md5($methodName . serialize($parameters));
if (!isset($this->cache[$id])) {
try {
$class = new ReflectionClass($this->object);
$method = $class->getMethod($methodName);
$this->cache[$id] = $method->invoke(
$this->object,
$parameters[0],
$parameters[1]
);
}
catch (ReflectionException $e) {
}
}
return $this->cache[$id];
}
}
?>
Die Generizität wird durch Verwendung der Reflection API
(„Die Reflection API“) erreicht.
Der Interzeptor nutzt diese, um beim Aufruf einer von der Klasse
Cache nicht selbst zur Verfügung gestellten Methode
zu testen, ob das aggregierte Objekt $object die
geforderte Methode besitzt.
Beispiel 2.7: Die Klasse Rechner
<?php
class Rechner {
public function rechne($a, $b) {
print "Rechner::rechne($a, $b) ausgeführt.\n";
return $a * $b;
}
}
?>
Beispiel 2.8 zeigt
die Verwendung der Klasse Cache am Beispiel eines
Rechner-Objektes
(Beispiel 2.7).
Beispiel 2.8: Verwendung der Klassen Cache und Rechner
<?php
require_once 'Cache.php';
require_once 'Rechner.php';
$rechner = new Cache(new Rechner);
$rechner->rechne(23, 42);
$rechner->rechne(23, 42);
?>Rechner::rechne(23, 42) ausgeführt.