Ich beschäftige mich gerade mit der objektorientierten Programmierung in PHP und versuche mein CMS so fast komplett neu umzusetzen und zu erweitern. Ein Problem war da aber: Wie setzt man am besten Objektinstanzen (z.B. von der Datenbank Klasse) global verfügbar?
Problem von "global"
<?php
$test_var = 'Hello World';
function test_function() {
global $test_var;
echo $test_var;
}
test_function();
?>
So einfach würde es gehen, Variablen vom lokalen Geltungsbereich auch in einer Funktion/Methode verfügbar zu machen. Warum man es dennoch nicht nutzen sollte:
- Wiederverwendung von Code-Teilen wird erschwert wegen möglicherweise anderen Variablennamen.
- Das finden von Fehlern wird erschwert, weil eine globale Variable überall definiert werden könnte.
- Die Übersichtlichkeit leidet darunter, wenn sehr viele globale Variablen verwendet werden und somit wird es wahrscheinlich schwerer den Code später zu verstehen.
Abhilfe mit Singletons und Registry Pattern
<?php
class registry {
private $objects = array();
public function &load() {
static $me;
if(!is_object($me)) {
$me = new registry();
}
return $me;
}
public function set($name, &$object) {
$this->objects[$name] =& $object;
}
public function &get($name) {
return $this->objects[$name];
}
}
function instance_require($class) {
$registry =& registry::load();
$args = func_get_args();
if(count($args) > 1) {
$ref = array();
foreach($args as $arg) {
$ref[] =& $registry->get($arg);
}
} else {
$ref =& $registry->get($args[0]);
}
return $ref;
}
?>
Die Grundidee hinter diesem Code besteht darin, alle Instanzen der Objekte zu registrieren und dann später über die Funktion instance_require in den Methoden verfügbar zu machen. Singleton wird die load-Methode der registry-Klasse genannt. Singleton, weil dieses Modell nur eine Instanz der registry-Klasse zulässt.
Verwendung
Als erstes muss die registry geladen werden um benötigte Instanzen zur registry hinzuzufügen:
<?php
// Instance registry
$registry =& registry::load();
// Register instances
$db = new database();
$registry->set('db', $db);
$var = new variable();
$registry->set('var', $var);
?>
Später können die registrierten Instanzen dann bequem über die Funktion instance_require geladen, bzw. referenziert werden:
<?php
class test {
public function test_RequireOneInstance() {
$database = instance_require('db')
// Work with database
}
public function test_RequireMoreInstances() {
list($var, $MyDBName) = instance_require('var', 'db');
// Work with both instances using only one line of code.
// Isn't that nice? :o)
}
}
?>
Quelle und mehr zum Thema gibt es auf www.phpit.net.

L3o am 08. Februar 2011, 18:41 Uhr
Danke, das rettet mir den Tag, ich schreibe nämlich im Moment gerade selbst ein Framework, und das war mein grösstes Problem (bis jetzt ;-) ).