2009-02-15 3 views
5

Ich habe eine Klasse für die Interaktion mit einem Memcache-Server. Ich habe verschiedene Funktionen zum Einfügen, Löschen und Abrufen von Daten. Ursprünglich hat jede Funktion einen Aufruf an memcache_connect() jedoch die unnötig war, z.B .:Share Variablen zwischen Funktionen in PHP ohne Verwendung von globalen

mc->insert() 
mc->get() 
mc->delete() 

drei memcache Verbindungen machen würde. Ich arbeite, um diesen durch ein Konstrukt für die Klasse zu erstellen:

function __construct() { 
    $this->mem = memcache_connect(...); 
} 

und dann $this->mem, wo immer die Ressource benötigt wurde, so dass jede der drei Funktionen verwendet die gleiche memcache_connect Ressource.

Das ist in Ordnung, aber wenn ich die Klasse in anderen Klassen nennen, z.B .:

class abc 
{ 
    function __construct() { 
     $this->mc = new cache_class; 
    } 
}  
class def 
{ 
    function __construct() { 
     $this->mc = new cache_class; 
    } 
} 

dann ist es immer noch zwei memcache_connect Anrufe tätigen, wenn es nur Bedürfnisse ein.

Ich kann dies mit Globals tun, aber ich würde es vorziehen, sie nicht zu verwenden, wenn ich nicht muss.

Beispiel Globals Umsetzung:

$resource = memcache_connect(...); 

class cache_class 
{ 
    function insert() { 
     global $resource; 
     memcache_set($resource , ...); 
    } 
    function get() { 
     global $resource; 
     return memcache_get($resource , ...); 
    } 

} 

Dann egal wie oft die Klasse dort genannt wird, wird nur ein Aufruf an memcache_connect sein.

Gibt es eine Möglichkeit, dies zu tun oder sollte ich nur Globals verwenden?

Antwort

9

ich eine andere Klasse mit Singletonmuster für das Erhalten der einzige Fall von memcache Code würde. So -

class MemCache 
{ 
    private static $instance = false; 
    private function __construct() {} 

    public static function getInstance() 
    { 
    if(self::$instance === false) 
    { 
     self::$instance = memcache_connect(); 
    } 

    return self::$instance; 
    } 
} 

und Nutzung -

$mc = MemCache::getInstance(); 
memcache_get($mc, ...) 
... 
+0

Es ist eine vernünftige Lösung, aber seien wir ehrlich, es ist eine globale. :) – cletus

+0

Das ist, was ich tun würde. Du kannst es nicht testen, aber lass uns ehrlich sein, wer testet sowas überhaupt? –

+0

Die Frage ist, wie testbar der Rest des gesamten Codes bleibt, wenn ein kleiner Teil nicht testbar ist. Oder wie würden Sie ein simuliertes MemCache-Objekt für andere Tests implementieren? – okoman

5

Pass im MC Beispiel:

class abc 
{ 
    function __construct($mc) { 
     $this->mc = $mc; 
    } 
}  
class def 
{ 
    function __construct($mc) { 
     $this->mc = $mc; 
    } 
} 

$mc = new cache_class; 
$abc = new abc($mc); 

usw.

2

Ich glaube, Sie für statische Eigenschaften hier suchen.

class mc { 
    private static $instance; 

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

    private function __construct() { 
     $this->mem = memcache_connect(...); 
    } 
} 

Dies implementiert ein grundlegendes Singleton-Muster. Anstatt den Objektaufruf zu erstellen, rufen Sie mc::getInstance(). Schauen Sie sich singletons an.

+0

Lustig, wie Leute unten abstimmen, nachdem sie nicht mehr als den ersten Satz einer Antwort gelesen haben. +1 erneut. – Tomalak

1

Sie sollten die Abhängigkeitsinjektion verwenden. Das Singleton-Muster und die statischen Konstrukte werden als schlechte Praxis angesehen, weil sie im Grunde globale Variablen sind (und aus gutem Grund - sie zementieren, dass Sie jede Klasse verwenden, die Sie instanziieren, im Gegensatz zu anderen).

Hier ist etwas, was Sie tun sollten, um eine einfache Wartung zu haben.

class MemCache { 
    protected $memcache; 

    public function __construct(){ 
     $this->memcache = memcache_connect(); 
    } 
} 

class Client { 
    protected $MemCache; 

    public function __construct(MemCache $MemCache){ 
     $this->MemCache = $MemCache; 
    } 

    public function getMemCache(){ 
     return $this->MemCache; 
    } 
} 

$MemCache = new MemCache(); 
$Client = new Client($MemCache); 
$MemCache1 = $Client->getMemCache(); 

// $MemCache and $MemCache1 are the same object. 
// memcache_connect() has not been called more than once.