5 Stimmen

Freigabe von Variablen zwischen Funktionen in PHP ohne Verwendung von Globals

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 machte jede Funktion einen Aufruf an memcache_connect() Das war jedoch unnötig, z.B.:

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

würde drei Memcache-Verbindungen herstellen. Ich habe dies durch die Erstellung eines Konstrukts für die Klasse umgangen:

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

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

Das ist in Ordnung, aber wenn ich die Klasse innerhalb anderer Klassen aufrufe, z.B.:

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

dann macht es immer noch zwei memcache_connect Anrufe, wenn sie nur braucht ein.

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

Beispiel für die Implementierung von Globals:

$resource = memcache_connect( ... );

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

}

Unabhängig davon, wie oft die Klasse aufgerufen wird, gibt es dann nur einen Aufruf an memcache_connect .

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

9voto

Martin Jonáš Punkte 2299

Ich würde eine andere Klasse mit Singleton-Muster für das Erhalten der einzigen Instanz von memcache Code. Wie dies -

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 Stimmen

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

0 Stimmen

Ich würde Folgendes tun. Man kann es nicht testen, aber seien wir ehrlich, wer testet so etwas überhaupt?

0 Stimmen

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?

6voto

Greg Punkte 10290

Pass in der MC-Instanz:

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.

2voto

Ross Punkte 44536

Ich glaube, Sie suchen hier nach statischen Eigenschaften.

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

Damit wird ein grundlegendes Singleton-Muster implementiert. Anstatt das Objekt zu konstruieren, rufen Sie mc::getInstance() . Schauen Sie sich an Einzelnes .

0 Stimmen

Seltsam, wie Leute ihre Stimme abgeben, nachdem sie nicht mehr als den ersten Satz einer Antwort gelesen haben. Wieder +1.

1voto

Ryan Williams Punkte 961

Sie sollten Dependency Injection verwenden. Das Singleton-Muster und statische Konstrukte gelten als schlechte Praxis, weil sie im Wesentlichen Globals sind (und das aus gutem Grund - sie zementieren Sie auf die Verwendung der Klasse, die Sie instanziieren, im Gegensatz zu einer 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.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X