PHP erlaubt die spontane Erzeugung von Instanzvariablen
in einem Objekt zur Laufzeit, ohne dass diese vorher deklariert
werden müssen. Diese Instanzvariablen sind implizit public.
Mit Hilfe der Methoden __get($memberName) und
__set($memberName, $value) kann dieses Verhalten angepasst
und so genannte virtuelle Instanzvariablen realisiert werden.
Die Klasse VirtualMembers aus
Beispiel 2.4
setzt das Standardverhalten beim Zugriff auf nicht deklarierte Instanzvariablen
für ihre Objekte außer Kraft. Sie speichert den Inhalt dieser Variablen
in einem Array, das in einer als private deklarierten
Instanzvariablen liegt.
Beispiel 2.4: Implementierung von virtuellen Instanzvariablen
<?php
class VirtualMembers {
private $virtualMembers = array();
public function __get($memberName) {
@return $this->virtualMembers[$memberName];
}
public function __set($memberName, $value) {
$this->virtualMembers[$memberName] = $value;
}
}
?>
Beispiel 2.5
zeigt mit der Klasse Person einen möglichen Verwendungszweck für
virtuelle Instanzvariablen. Die Klasse Person kapselt
Personeninformationen, die in einer Tabelle personen in einer
Datenbank abgelegt sind. Eine Zeile dieser Tabelle entspricht einer Person,
die Spalte id identifiziert jede Person eindeutig
(Primärschlüssel). Durch Verwendung von virtuellen Instanzvariablen
erlaubt diese Klasse transparenten Schreib-/Lesezugriff auf die Personentabelle
über ein Personenobjekt.
Beispiel 2.5: Virtuelle Instanzvariablen im Einsatz
<?php
require_once 'MyProject_DB.php';
class Person {
private $db;
private $id;
private $cache = array();
private $fields = array('name');
public function __construct($id) {
$this->db = new MyProject_DB;
$this->id = $id;
}
public function __get($memberName) {
if (!in_array($memberName, $this->fields)) {
return;
}
if (!isset($this->cache[$memberName])) {
$this->db->query(
sprintf(
"SELECT %s
FROM personen
WHERE id = '%d';",
$memberName,
$this->id
)
);
if ($row = $mysql->fetchRow()) {
$this->cache[$memberName] = $row['name'];
}
}
return $this->cache[$memberName];
}
public function __set($memberName, $value) {
if (!in_array($memberName, $this->fields)) {
return;
}
$this->db->query(
sprintf(
"REPLACE INTO personen
(id, %s)
VALUES ('%d', '%s');",
$memberName,
$this->id,
$value
)
);
$this->cache[$memberName] = $value;
}
}
?>