[PHP] Existierende Objekte finden

fliegenkiller

Lt. Junior Grade
Registriert
März 2005
Beiträge
387
Hallo,

ich habe ein Objekt, welches eine Datenbankverbindung herstellt. Nur wenn das Objekt neu erstellt oder mit dem Parameter "New" aufgerufen wird, dann wird eine Verbindung hergestellt. Bei einer 2. Erstellung wird dann überprüft, ob bereits eine Verbindung besteht und dann wird die mysql_connect() Methode nicht ausgeführt.

Nun möchte ich, dass wenn ein Objekt zerstört wird, der Destruktor aufgerufen wird. Man kann das in der Klasse mit der Methode __destruct() erledigen. Jetzt möchte ich überprüfen, ob das zu zerstörende Objekt, das letzt seiner Art ist. Wenn es dann das letze ist, soll die Funktion mysql_close() aufgerufen werden.

[ich weiss, dass die Verbindung zum DB-Server automatisch beendet wird, wenn das Script abgearbeitet ist. Aber ich möchte diese Funktion bereitstellen.]

Gibt es eine Funktion, die man ausführen kann, welche dann die Nicht benötigten Objekte löscht? vgl. Garbage Collector in C#

Bestendank für eure Antworten
 
Also wenn alle Objekte in einem Array stehen und die Objekte nach der Zerstörung gleich 0 gesetzt werden, dann müsste das einfach mit ner Schleife gehen.

PHP:
$array = array($verbindungsobjekt1, $verbindungsobjekt2,...);

$alle_geloescht = true;

for($i=0;$i<count($array);$i++) {
    if($array[$i]!=0) {
        $alle_geloescht = false;
        break;
    }
}
if($alle_geloescht) mysql_close();
 
Stimmt, daran habe ich gar noch nicht gedacht. Man kann ja eine Statische Objekt Variable 'Count' definieren, die bei jeder erzeugung um eins erhöht wird und bei jeder Zerstörung um eins verringert wird. Dann kann man überprüfen, ob der Wert == 1 ist, dann kann die Verbindung zurückgesetz werden.

Danke dass du mich auf die Idee gebracht hast. Statt die Objekte in einem Array, speichere ich nun die Anzahl.
 
Wie wärs mit dem Singleton-Design Pattern?

also
PHP:
    function singleton() {
        static $instance;
        if(!$instance) {
            $instance = new mysqlobj;
        }
        return $instance;
    }

Bei PHP 4 müsstest du noch ein Paar & einfügen ;)
 
Danke für deine Antwort. Wie ich das jetzt Richtig verstanden habe, wird durch den Aufruf der singeton() Funktion ein Objekt erzeugt. Wurde schon ein Objekt erzeugt, dann wird nur noch die existierende Referenz zurück gegeben. Die Idee ist gar nicht mal so schlecht:

Ich habe eine Datei database.inc.php und mehrere Dateien für die einzelnen DB Typen: mysql, mssql, postgre etc.
Die Datenbankverbindung wird dann mit der Statischen Methode
PHP:
Database::OpenDatabase($new = false, $dbtype = 'default'){...}
aufgerufen. Die Funktion wertet danach das Configfile aus und gibt dann ein Objekt zurück.
Jetzt kann ich zwei Variablen Database::Ressource und Database::RessourceType definieren. Wenn jetzt zweites Objekt mit den gleichen Parameter erzeugt wird, dann wird nur noch die Kopie von diesem existierenden Objekt übergeben.

ich hoffe, dass ich das jetzt richtig verstanden habe.
 
Um den richtigen Typ der Datenbankverbindung auszuwählen, könntest du eine weitere methode erstellen - das wäre dann die Factory-Methode:

PHP:
function factory($datenbank_typ) {
    return Database::OpenDatabase(true, $datenbank_typ);
}
function singleton($dsn = "default") {
        static $instance = array();
        
        if($dsn === "default") {
            $dsn = config_get('database_config');
        }

        $key = md5(serialize($dsn));

        if(!$instance[$key]) {
            $instance[$key] = Database::factory($dsn);
        }
        return $instance[$key];
    } 
}

Ein DSN könnte ein Array mit folgenden Werten sein:
array('backend' => 'mysql', 'hostname' => ..., 'username' => ..., 'password' => ..., 'database' => ...);

Das Factory-Design Pattern verwendet man "zum Erzeugen eines Objektes, aber lasse unterklassen entscheiden, von welcher Klasse das zu erzeugende Objekt ist.".

Also du überlässt der Fabrikmethode welche Art von Datenbank dahinter hängt. Singleton ist nur dafür zuständig eine eindeutige instanz einer Ressource zu holen. Klar kannst du auch darin die config parsen und weitere Daten holen.

Mit der Vorgehensweise könntest du dann auch ohne Probleme mehrere Datenbankverbindungen parallel verwalten:

PHP:
$dsn1 = array(...);
$dsn2 = array(...);

$db_klasse1 = Database::singleton($dsn1);
$db_klasse2 = Database::singleton($dsn2);

$db_klasse3 = Database::singleton($dsn1); // == $db_klasse1
 
Nochmals danke für deine Antwort. Jedoch ist es zur Zeit noch nicht notwendig mehrere dauerhafte Datenbankverbindungen verwalten zu können. Bei dem meisten Hoster hat man so oder so nur eine Datenbank zur verfügung bzw. man nutzt für ein Projekt nur eine.
Ich möchte nur die Möglichkeit bieten, wenn man jetzt eine Abfrage in einer anderen Db ausführen will, kann man dies erledigen.

Mit deiner Methode ist es ganz sicher besser gelöst, aber es übersteigt die Möglichkeiten die ich in der ersten Version vergeben möchte. Viellecith kommt es in der 2. Version.

Danke!

Zum Schluss noch eine kleine Frage, die nich ganz zum Thema gehört: Gibt es eine Möglichkeit, ein Speicherabbild zu erstellen? D.h. Falls ein Script einen Fehler auswirft, werden alle Klassen, Funktionen, Methoden, Variablen etc in einem Array oder String gespeichert und man kann die Daten dann auswerten? Ich hatte mal etwas getestet, jedoch wenn ich es in einer Funktion ausgeführt habe, bekam ich nur die Daten der Funktion und nicht die Umgebung.
 
kuck dir mal die Funktion
debug_backtrace()
an.
 
Ja danke. Sieht nicht schlecht aus, was diese Funktion liefert. Es zeigt auch die Parameter, mit der die Funktion gerufen wird an, ist es möglich, dass es auch die rufende Funktion anzeigt?
 
Zurück
Oben