Überladung
Überladung bietet in PHP Möglichkeiten, um dynamisch
Eigenschaften und Methoden zu erzeugen
.
Diese dynamisch erzeugten Entitäten werden unter
Zuhilfenahme von magischen Methoden verarbeitet,
die man in einer Klasse zu verschiedenen Aktivitäten
definieren kann.
Die Überladungsmethoden werden aufgerufen, wenn mit
Eigenschaften oder Methoden interagiert wird, die entweder
nicht deklariert wurden oder im aktuellen Geltungsbereich
nicht sichtbar
sind. Im Rest dieses Abschnitts werden die Begriffe
unzugreifbare Eigenschaft
und
unzugreifbare Methode
verwendet, um auf die
Kombination von Deklaration und Sichtbarkeit zu verweisen.
Alle Überladungsmethoden müssen als public
definiert sein.
Hinweis:
Keiner der Parameter dieser magischen Methoden kann
als
Referenz übergeben werden.
Hinweis:
Die Interpretation von Überladung
weicht
von den meisten objektorientierten Programmiersprachen
ab. Traditionell bezeichnet Überladung die Möglichkeit
mehrere Methoden mit gleichem Namen aber unterschiedlichen
Anzahlen und Typen von Parametern zu definieren.
Überladung von Eigenschaften
__set wird aufgerufen, wenn Daten in
unzugreifbare (protected oder private) Eigenschaften geschrieben werden
sollen.
__get wird verwendet, um Daten aus
unzugreifbaren (protected oder private) Eigenschaften zu lesen.
__isset wird aufgerufen, indem
isset() oder empty()
auf unzugreifbare (protected oder private) Eigenschaften angewendet wird.
__unset wird aufgerufen, wenn
unset() für unzugreifbaren (protected oder private)
Eigenschaften aufgerufen wird.
Der Parameter $name beinhaltet den Namen
der Eigenschaft, mit der interagiert wird. Der Parameter
$value der Funktion __set
spezifiziert den Wert den die Eigenschaft $name
annehmen soll.
Überladung von Eigenschaften funktioniert nur im Kontext von
Objekten. Diese magischen Methoden werden nicht aus einem
statischen Kontext aufgerufen. Diese Methoden sollten daher
nicht als static
deklariert werden. Eine Warnung wird ausgegeben,
wenn eine dieser magischen Überladungsmethoden als
static
deklariert ist.
Hinweis:
Der Rückgabewert von __set wird, aufgrund
der Behandlung des Zuweisungsoperators in PHP, ignoriert.
Aus ähnlichen Gründen wird __get nicht
aufgerufen, wenn man Zuweisungen in etwa wie folgt verkettet:
Hinweis:
PHP ruft niemals eine überladene Methode von derselben überladenen
Methode aus auf. Das bedeutet zum Beispiel, dass
return $this->foo
innerhalb von
__get() null
zurückgibt und ein
E_WARNING
auslöst, wenn die Eigenschaft
foo
nicht definiert ist, anstatt
__get() ein zweites Mal aufzurufen. Es
ist jedoch möglich, dass eine überladene Methode implizit eine andere
überladene Methode aufruft (z. B. löst
__set() den Aufruf von
__get() aus).
Beispiel #1
Überladung von Eigenschaften mit den Methoden
__get, __set,
__isset und __unset
<?php
class EigenschaftTest
{
/** Speicherplatz für überladene Daten. */
private $data = array();
/** Überladung wird nicht bei deklarierten Eigenschaften benutzt. */
public $declared = 1;
/** Überladung wird nur von außerhalb der Klasse angewendet. */
private $hidden = 2;
public function __set($name, $value)
{
echo "Setze '$name' auf '$value'\n";
$this->data[$name] = $value;
}
public function __get($name)
{
echo "Lese '$name'\n";
if (array_key_exists($name, $this->data)) {
return $this->data[$name];
}
$trace = debug_backtrace();
trigger_error(
'Undefinierte Eigenschaft für __get(): ' . $name .
' in ' . $trace[0]['file'] .
' Zeile ' . $trace[0]['line'],
E_USER_NOTICE);
return null;
}
public function __isset($name)
{
echo "Ist '$name' gesetzt?\n";
return isset($this->data[$name]);
}
public function __unset($name)
{
echo "Lösche '$name'\n";
unset($this->data[$name]);
}
/** Keine magische Methode, nur beispielhaft hier. */
public function getHidden()
{
return $this->hidden;
}
}
$obj = new EigenschaftTest;
$obj->a = 1;
echo $obj->a . "\n\n";
var_dump(isset($obj->a));
unset($obj->a);
var_dump(isset($obj->a));
echo "\n";
echo $obj->declared . "\n\n";
echo "Wir experimentieren nun mit der private-Eigenschaft 'hidden':\n";
echo "Private ist innerhalb der Klasse sichtbar, also wird __get() nicht benutzt...\n";
echo $obj->getHidden() . "\n";
echo "Private nicht sichtbar von außerhalb der Klasse, also wird __get() benutzt...\n";
echo $obj->hidden . "\n";
?>
Das oben gezeigte Beispiel erzeugt folgende Ausgabe:
Setze 'a' auf '1'
Lese 'a'
1
Ist 'a' gesetzt?
bool(true)
Lösche 'a'
Ist 'a' gesetzt?
bool(false)
1
Wir experimentieren nun mit der private-Eigenschaft 'hidden':
Private ist innerhalb der Klasse sichtbar, also wird __get() nicht benutzt...
2
Private nicht sichtbar von außerhalb der Klasse, also wird __get() benutzt...
Lese 'hidden'
Notice: Undefinierte Eigenschaft für __get(): hidden in <file> Zeile 70 in <file> on line 29
Überladung von Methoden
__call wird aufgerufen, wenn eine unzugreifbare
Methode in einem Objekt aufgerufen wird.
__callStatic wird aufgerufen, wenn eine
unzugreifbare Methode in einem statischen Kontext aufgerufen wird.
Der Parameter $name ist der Name der aufgerufenen
Methode. Der Parameter $arguments beinhaltet ein
Array mit den Parametern, die der Methode $name
übergeben wurden.
Beispiel #2
Überladung von Methoden mit den methoden __call
und __callStatic
<?php
class MethodenTest {
public function __call($name, $arguments)
{
// Achtung: Der Wert von $name beachtet die Groß-/Kleinschreibung
echo "Rufe die Objektmethode '$name' "
. implode(', ', $arguments). "\n";
}
public static function __callStatic($name, $arguments)
{
// Achtung: Der Wert von $name beachtet die Groß-/Kleinschreibung
echo "Rufe die statische Methode '$name' "
. implode(', ', $arguments). "\n";
}
}
$obj = new MethodenTest;
$obj->runTest('eines Objektes auf');
MethodTest::runTest('aus statischem Kontext auf');
?>
Das oben gezeigte Beispiel erzeugt folgende Ausgabe:
Rufe die Objektmethode 'runTest' eines Objektes auf
Rufe die statische Methode 'runTest' aus statischem Kontext auf