Wenn Herr
Ssilk das jetzt lesen würde, würde er rülpsen. Ein Insider, zugegeben.
Ok, kaltes Wasser: Angenommen, eine Anwendung muss mit tausenden Array-Keys jonglieren (oder besser gesagt, zehntausenden, um eine reale Vorstellung von schönen Anwendungen zu bekommen). Und um das Beispiel etwas wilder zu gestalten, greifen wir auf die PHP-Session zu, weil wir eine Ajax-Anwendung haben und für jede Anfrage nur persistente Daten auftauen möchten.
Wir haben also im Code an multiplen Stellen sowas stehen:
$affiliate_program_id = $_SESSION['tns']['affiliate_program_id'];
Schlaue Leute kappseln die Session-Zugriffe über ein Singleton. Nennen wir es mal unsere Registry. Sie hat einen Getter und einen Setter. Wir holen die Daten wie folgt aus dem persistenten Land:
$affiliate_program_id = Registry::getInstance()->get('affilliate_program_id');
Schöne OO-Welt, denn ein Spassvogel im Entwickler-Team verschreibt sich dennoch (das Vorhandensein von Legastenie bedeutet nur, dass man toll im Bett, aber nicht zwingend blöde ist). Der Wert von $affiliate_program_id wird NULL sein, obwohl ein Wert gesetzt ist. Da hilf leider auch kein Tool.
Wer den Aufwandt aber nicht scheut - und langfristig zahlt sich das aus - der sollte auf die Verwendung von Array-Schlüsseln verzichten. Jedenfalls im Anwenungsland, in dem die Kollegen unsere Objekte verwenden - im Objektland selber kann das meist getestet werden (in dem Fall ist es nicht unbedingt schlimm, wenn weiterhin ungehemmt mit wilden Array-Schlüsseln herumgesaut wird).
Hier, wie eine unvollständige Implementierung aussehen könnte:
class Registry {
/**
* Magic getter
*
* @param string $name property name
* @return mixed value or NULL if not defined
*/
public function __get($name) {
if ($this->is_set($name)) {
$val = $this->get($name);
return (is_array($val)) ? (object)$val : $val;
}
return null;
}
}
Im Anwendungsland bekommt man so Daten aus dem persintenten Land:
$reg = Registry::getInstance();
$affiliate_program_id = $reg->affilliate_program_id
Beim genauen Betrachten haben wir also überhaupt nichts gewonnen, weil wir jetzt immer noch auf eine Property zugreifen, die nicht existiert, weil ich mich verschrieben habe.
Was ich ja aber eben nicht will ist, in meiner Registry jedes Property zu definieren. Ich will einen Weg finden, der mir den Zugriff wenigstens auf im Projekt allgemein verwendeten Properties halbwegs "absichert". Wir haben es bei PHP immer noch mit einer Script-Sprache zu tun...
Was soll dieser Eintrag dann? Ich möchte einfach mal eine Lanze für IDEs brechen. Die meisten haben nämlich eine Autovervollständigung eingebaut. Und die triggern wir jetzt an:
In einem beliebigen Verzeichnis innerhalb des Projekt, in dem die Datei Registry.php liegt, legen wir zusätzlich eine Deitei an, z. B.:
~/Codecompletion/ZDE/Registry.php
Wir implementieren in dieser Datei die Klasse einfach nochmal als Dummy-Klasse:
# Es macht keinen Sinn, diese Datei auszuführen...
exit;
class Registry {
/**
* Holds the persistent id of
* current affilate program.
* @var int
*/
public $affiliate_program_id
/**
* Singleton.
*
* @return Registry
*/
public static function getInstance() {}
}
Die Singleton-Methode kann ausschließlich in der Klasse dokumentiert werden, in der sie verwendet wird. Ich hab' das hier mal einfach doppelt gemacht, damit mein Beispiel schön läuft.
So, und wenn ich mir eine Instanz hole, hab ich auch gleich die Autovervollständigung:
Der nächste Schritt könnte nun ein Parser sein, der die Dateien für die Autovervollständigung wenigstens anlegt, wenn eine Klasse z. B. die magic methods __get und __set bereitstellt...
Aber das ist eine andere Geschichte. Und die Arbeit ruft wieder.