Letzte Kommentare

PlayJaps: Ïðèâåò Æäåì íà ñòîïî÷êó :) Êëàññíî! KAPOW…

Klaus: Guten Tag, ich habe Ihre Seite über die Google-Suche gefunden, weil…

Michael: Hallo Josef, Wo du die gezeigte Funktion hinein kopierst ist ziemlich…

Josef: Guten Tag! Ich habe mich mit der PHP-Template-Thematik noch nie beschäftigt.…

L3o: Danke, das rettet mir den Tag, ich schreibe nämlich im Moment gerade selbst…

Zum mitnehmen

Für Programmierer:

Für Anwender:

OOP: Globale Instanzen, Singletons und Registry Pattern

Tags: php, oop 1 Kommentar

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:

  1. Wiederverwendung von Code-Teilen wird erschwert wegen möglicherweise anderen Variablennamen.
  2. Das finden von Fehlern wird erschwert, weil eine globale Variable überall definiert werden könnte.
  3. 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.

Kommentare

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 ;-) ).

Kommentar schreiben

  • Erlaubte HTML Tags: <a> <code> <em> <strong> <small> <ul> <ol> <li> <blockquote>
  • Zeilen und Absätze werden automatisch formatiert.
  • Web und E-Mail Adressen werden automatisch umgewandelt.