Destruktor wird zu früh aufgerufen.

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Destruktor wird zu früh aufgerufen.

    Tag,

    habe ein Problem mit einer SQL-Klasse. Als Destruktor-Ablauf wird dort eine bestehende Datenbank-Verbindung (die anhand einer Eigenschaft der Klasse definiert wird) wieder geschlossen. Folgendes Skript benutzt diese Klasse namens "mysql":

    PHP-Code:

    /* gotophp-bookmark file */

    require_once("../config-inc.php5");
    require_once(
    "db-mysql-inc.php5");
    require_once(
    "session-phpbb-inc.php5");

    $sql= new mysql;
    $sql->query("SELECT pid FROM gtp_pages WHERE...");

    if(
    $sql->rows() == 0) { throw new Exception("Unknown chapter-id or page-timestamp given, did you manipulate the URL?"); }

    $sess = new bbsession;

    if(
    $sess->state())
        {
        
        
    setcookie("sp_gtp"""time()-60"/"$cfg["domain"]);
    print 
    "1";
        
    $sql->query("UPDATE users SET....");    

        
    header("LOCATION: ./".$input->get["c"]."/".$input->get["p"]."/");
        }
    else
        {
        
        
    setcookie("sp_gtp"$input->get["c"]."_".$input->get["ts"]."_".$input->get["p"], time()+(60*60*24*300), "/"$cfg["domain"]);

        
    header("LOCATION: ./".$input->get["c"]."/".$input->get["p"]."/");    
        }

    ?> 
    Der Query wird dem Konstruktor der Klasse übergeben, habe die jetzt mal gekürzt, damit es das Forum-Layout nicht auseinanderreißt. Problematisch wird es mit dem erneuten Aufruf der der Methode Query in Zeile 21. Zu diesem Zeitpunkt (das beweise Testausgaben vom Destruktor und dem print "1" darüber) ist der Destruktor vom Objekt "sql" schon gerufen und die Verbindung geschlossen worden, und der Query wird mit Standard-Verbindungsdaten aus der php.ini abgesetzt, was natürlich fehlschlägt.

    Die MySQL-Klasse ist angehängt.
    Angehängte Dateien

  • #2
    Sorry, aber du übergibst dem Konstruktor überhaupt nichts. Du übergibst der Methode query() etwas (nämlich den String mit der Anfrage).
    Mach mal ein var_dump() von $sql direkt bevor und nachdem du bbsession instanziert hast.
    Zuletzt geändert von Nezzar; 21.12.2004, 16:03.
    "Ach was soll's? Dann bau ich mir halt meinen eigenen Vergnügungspark mit Blackjack und Nutten." - Bender

    Kommentar


    • #3
      Original geschrieben von Nezzar
      Sorry, aber du übergibst dem Konstruktor überhaupt nichts.
      Das ist richtig. Sieh dir mal die Klasse an. Der Konstruktor ist so aufgebaut, dass er (falls nötig) erstmal ne Verbindung aufbaut, und nen Verbindungs-Handler erzeugt. Wird etwas als Argument übergeben, gibt er das an die Methode query() weiter. Ich instantiiere die Klasse erstmal ohne Query, um nen Verbindungs-Handler zu bekommen, den ich dann mysql_real_escape_string() übergeben kann, das funktioniert natürlich beim Erstellen der Objekt-Instanz noch gar nicht, deswegen muss ich es so machen.

      Aber es is so, wie ich es befürchtet hatte. Die Eigenschaft myql::link_handler wird nach der Instantiierung von bbsession in $sess zu einer resource vom Typ "unknown". Vorher kann ich der Methode mysql::query() beliebig viele neue Aufrufe mit Anfragen geben, die ich alle wunderbar behandeln kann. So in etwa:

      PHP-Code:
      <?php

      $sql 
      = new mysql;

      $sql->query("dsfsdf");

      var_dump($sql->result());

      $sql->query("bla bla");

      var_dump($sql->result());

      ?>
      Nur sobald die Klasse bbsession eine Objektinstanz bekommt spinnt PHP und ruft den Destruktor von mysql auf, der die Verbindung natürlich löscht. Daraufhin hat mysql::query() keinen gültigen Verbindungs-Handler mehr und schlägt auch fehl.

      Verstehst du jetzt das Problem?

      bbsession benutzt auch die MySQL-Klasse, natürlich nicht mit dem Objekt $sql...aber trotzdem
      Zuletzt geändert von MaxPayne; 21.12.2004, 19:10.

      Kommentar


      • #4
        hi,

        schon mal probiert, deinen code in eine klasse zu packen, in dieser klasse von deiner mysql klasse zu extenden und dann den destructor zu überschreiben?

        Kommentar


        • #5
          Nette Idee, das löst aber nicht das Problem. Offensichtlich hab ich hier die Funktionsweise eines Destruktors nicht verstanden oder es handelt sich um einen Bug. Jedenfalls wird der Destruktor von "sql" mit der Instantiierung von "sess" gerufen, und das kann nicht im Sinne des Erfinders sein.
          Ich denke ein Destruktor wird gerufen wenn alle Referenzen auf ein Objekt verschwinden oder dieses zerstört wird?

          Kommentar


          • #6
            Nachtrag

            Im Prinzip ist ein Destruktor der mysql_close() ruft auch Quark, wegen dem Garbage-Collector von PHP.
            Aber ich meine hat denn niemand ähnliche Erfahrungen oder nutzt OOP kaum einer? Eher letzteres was...

            Kommentar


            • #7
              also ich benutzte mittlerweile nur noch php5, aber da ich auch viel mit java mache, hab ich nicht viel mit destruktoren im sinn.

              ich verstehe aber nicht ganz, warum bei dir noch ein mysql_close vorkommen soll? solange du kein pconnect verwendest wird die verbindung am ende des skripts von php ohnehin gekappt. und die objekte sind dann auch geschichte.

              mich interessiert der konkrete anwendungsfall, für den du den destructor benötigst.

              hier ein dblayer, den ich des öfteren verwende und der ziemlich goil ist
              http://adodb.sourceforge.net
              Zuletzt geändert von beebob; 25.12.2004, 07:48.

              Kommentar


              • #8
                Original geschrieben von beebob
                ich verstehe aber nicht ganz, warum bei dir noch ein mysql_close vorkommen soll? solange du kein pconnect verwendest wird die verbindung am ende des skripts von php ohnehin gekappt. und die objekte sind dann auch geschichte.
                Siehe meinen letzten Post. Trotzdem kann es nicht richtig sein, dass der Destruktor so früh gerufen wird, da brauch ich auch gar keinen...

                Kommentar

                Lädt...
                X