5 Stimmen

PHP: Wie übergibt man eine bestehende Datenbankverbindung an Methoden einer statischen Klasse?

Ich habe eine Reihe von statischen Klassenmethoden. Außerdem habe ich eine bestehende Datenbankverbindung in einem Skript, das in einer Objektvariablen $DB gespeichert ist. Wie rufe ich diese statischen Klassenmethoden auf und lasse sie das $DB-Objekt verwenden, ohne dass ich ihnen diese Variable jedes Mal als Parameter der Klassenmethode übergeben muss?

Im Moment muss ich zum Beispiel leider ein Global verwenden:

class Foo {
  public static function Bar() {
    global $DB;
    return $DB->DSN_STRING;
  }
}

Es ist wie ich meine statische Klasse benötigen, um sich mit einer Routine aufrufen, die irgendwie die $DB-Verbindung erhält, ohne es wiederherstellen zu müssen. Beachten Sie, ich kann es nicht in die statische Klasse injizieren, weil es nicht instanziiert ist.

Natürlich ist das Problem gelöst, wenn ich von einer statischen Klasse zu einer regulären Klasse wechsle und mein $Foo-Objekt instanziiere. Dann könnte ich die Variable $DB als Einstellung einer öffentlichen Variablen einfügen. Oder eine öffentliche Methode hinzufügen, um die $DB-Variable zu empfangen und dann eine private Variable des $Foo-Objekts zu setzen. Oder ich könnte einen Klassenkonstruktor so gestalten, dass er die $DB-Variable akzeptiert und eine private Variable des $Foo-Objekts setzt. Aber alle 3 Techniken erfordern, dass ich von einer statischen Klasse zu einer regulären Klasse wechsle.

Einige Leute haben etwas erwähnt, das Registry-Muster oder Singleton-Muster genannt wird (ich glaube, es ist dasselbe, bin mir aber nicht sicher). Ist dies, was ich brauche, um dieses Problem effizient zu lösen?

Vor allem vermeide ich es, "global $DB" zu nennen, weil die Leute darüber ausflippen.

10voto

zombat Punkte 89911

Ich würde dafür das Singleton-Muster verwenden, was ich auch tue. Ich verwende eine Klasse, die ich hier einfach Database_Manager nennen werde:

class Database_Manager
{
    private static $instance;
    private $db_connection;

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

    public static function initializeConnection($connectionInfo)
    {
        $db = self::getInstance();
        //call init functions.. connect to db, etc
            //save connection to $db->db_connection;

    }

    public static function getDb()
    {
        $db = self::getInstance();
        return $db->db_connection;
    }
}

Sie können die Dinge einmal mit dem Aufruf initializeConnection() einrichten und von da an nur noch Database_Manager::getDb() aufrufen.

Das Schöne an diesem Ansatz ist, dass er leicht modifiziert werden kann, um Verbindungen zu mehreren Datenbanken zu verwalten, und dass Sie garantiert immer nur eine offene Verbindung pro Datenbank haben werden.

Beachten Sie, dass ich einige der Feinheiten der Singleton-Implementierung weggelassen habe, wie z. B. die Deklaration der __construct()-Funktion als privat (das meiste davon ist aus dem Speicher kopiert). Ich wollte nur den allgemeinen Ansatz zeigen.

3voto

Darrell Brogdon Punkte 6659

Ich denke, ein Singleton würde gut funktionieren für das, was Sie zu tun versuchen. Andernfalls sind Sie darauf beschränkt, das Schlüsselwort "global" zu verwenden, das, wie Sie bereits herausgefunden haben, extrem teuer ist.

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