2009-08-03 31 views
2

Ich beginne gerade meine Reise in OOP - und ich versuche gerade, meine eigene MVC zu rollen - rein zu Lernzwecken. Ich arbeite an einem Tutorial im Apress PHP-Objects Patterns Practice Buch. Ich habe eine Registrierung Singleton-Objekt mit dem privaten __construct/__ Klon-Technik erstellt:Zugriff auf Singleton-Methoden in PHP

class Registry 
{ 
    private static $instance; 
    private $values = array(); 


    private function __construct(){} 
    private function __clone(){} 

    public static function getInstance(){ 
     if(!isset(self::$instance)){ 
     self::$instance = new Registry(); 
     } 
     return self::$instance; 
     } 

    public function get($key) { 
     if (isset($this->values[$key])) { 
      return $this->values[$key]; 
      } 
     return null; 
     } 

    public function set($key, $val) { 
     $this->values[$key] = $val; 
     } 
    } 

ich eine Instanz dieses Objekts direkt das heißt:

Registry::getInstance(); 

jedoch (im Anschluss an die Syntax im Tutorial) - wenn ich versuche, und Zugriff auf die öffentlichen Methoden der Verwendung von ‚->‘ Verfahren - zB:

Registry->setVal('page',$page); 

ich bekomme einen Parse-Fehler. Ich kann nur auf die Methoden zugreifen, die den Scope-Resolution-Operator verwenden - also '::'.

ich dies unter der Annahme ist, da das Objekt-Wrapper hat nicht gewesen instanziiert - aber ich will nur mit ihr alle dieses Problem verifizieren/diskutieren ...

Antwort

4

Registry::getInstance() gibt einen (in der Tat die einzige) Instanz der Klasse Registry. Es hat den gleichen Rückgabewert wie new Registry(), nur dass es in Ihrer gesamten Anwendung nur eine Instanz geben kann. Dies sind Ihre Möglichkeiten, um die Methoden zugreifen:

// #1 
$registry = Registry::getInstance(); 
$registry->set($key, $value); 

// #2 
Registry::getInstance()->set($key, $value); 

Ein weiterer Trick:

Map get() und set() ihrer magischen Methoden.

public function __set($key, $value) 
{ 
    return $this->set($key, $value); 
} 

public function __get($key) 
{ 
    return $this->get($key); 
} 

So können Sie entweder Registry::getInstance()->set($key, $value); oder Registry::getInstance()->$key = $value;

+0

Das beantwortet meine Frage .... Während ich hier bin - wenn ein früherer Prozess die Registry-Klasse mit Registry :: getInstance initialisiert - können nachfolgende nicht verwandte Klassen auf die Registry :: set() -Methoden verweisen, ohne durch dieselben zu springen hoop - oder muss ich dieses Objekt für jedes Objekt initialisieren, das auf seine Methoden zugreifen möchte? – sunwukung

1

Sie müssen setval anrufen() auf eine Instanz, nicht die Klasse selbst, so können Sie dies tun:

Registry::getInstance()->set('page', $page); 
0

Eine weitere Alternative ist die Objekterstellung in der Klasse zu setzen, anstatt hat es auf jeder Benutzung verweisen:

public static function get($key) { 
    $instance = self::getInstance(); 
    if (isset($instance->values[$key])) { 
     return $instance->values[$key]; 
    } 
    return null; 
} 

Und Anruf es mit nur Registry::set('page', $page);

Auf diese Weise machen Sie einen etwas schöneren Code, wo es verwendet wird, obwohl die singen leton sollte immer noch als ein Warnzeichen betrachtet werden (es gibt schon eine Menge guten Thread auf, warum auf Stackoverflow, wenn Sie suchen).