Autor Beitrag
Heiko
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3169
Erhaltene Danke: 11



BeitragVerfasst: Sa 03.11.07 19:18 
Hallo,

ich habe ein kleines Problem mit php. Und zwar nutzt von einer Klasse A die SubKlasse B die DB-Verbindung der Klasse A. im destructor von der Klasse B soll nun noch etwas an der Klasse A etwas gemacht werden. Und der destructor von der Klasse A soll DB-Verbindung mit einem close schließen.
Allerdings wird erst der Destructor der Klasse A durchlaufen und dann erst der Destructor der Klasse B. Kann man das verändern? Ich habe es schon versucht in dem ich unset(Klasse B) im destrcutor von Klasse A (vorm $db->close) aufrufe, allerdings wird der Destructor der Klasse B trotzdem erst nach dem Destructor von Klasse A aufgerufen.

Gibt es zu dem Problem eine Lösung? Unter Delphi ist das ja kein Problem (da es kein gc gibt, sondern man alles manuell machen muss)... :(.

Grüße
Heiko


Zuletzt bearbeitet von Heiko am Sa 03.11.07 20:59, insgesamt 1-mal bearbeitet
tommie-lie
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 4373

Ubuntu 7.10 "Gutsy Gibbon"

BeitragVerfasst: Sa 03.11.07 20:42 
Im PHP-Manual steht
Zitat:
Like constructors, parent destructors will not be called implicitly by the engine. In order to run a parent destructor, one would have to explicitly call parent::__destruct() in the destructor body.
Wie wäre es denn, den Aufruf an parent::__destruct() einfach ans Ende deines B::__destruct() zu setzen? Das sollte den Destruktor der Vaterklasse aufrufen, nachdem dein Destruktorcode von B ausgeführt wurde.

_________________
Your computer is designed to become slower and more unreliable over time, so you have to upgrade. But if you'd like some false hope, I can tell you how to defragment your disk. - Dilbert
Heiko Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3169
Erhaltene Danke: 11



BeitragVerfasst: Sa 03.11.07 20:57 
Das hatte ich schon probiert. Da meckert php rum, dass es keinen Vater gibt ;).

Ich geb mal kurz nen bissl Code zum Verständnis ;):

ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
class Main
{
  ...

  //DB-Verbindung
  private $db;

  ...
  public $curUser;
  ...

  //Konstruktor
  public function __construct()
  {
    ...
    //Datenbankverbindung herstellen
    $this->db = new dbAcp();

    ...
    $this->curUser    = new CurUser($this->db);
    ...
  }

  //Destruktor
  public function __destruct()
  {
    $this->db->close()
  }
  ...
}

class CurUser{
  ...

  //DB-Verbindung
  private $db;

  //Konstruktor
  public function __construct($use_db)
  {
    $this->db = $use_db;

    $this->session = new Session($this->db);
    ...
  }
  ...
}

class Session
{
  ...

  //Datenbankverbindung
  private $db;


  /**
  * Session anlegen oder fortsetzen
  *
  * @param integer $lifetime Lebensdauer der Session in Sekunden
  */

  public function __construct($use_db, $lifetime = 1800)
  {
    $this->db = $use_db;

    ...
        session_set_save_handler(array( &$this, "open" ),array( &$this, "close" ),array( &$this, "read" ),array( &$this, "write"),array( &$this, "destroy"),array( &$this, "gc" ));
  ...
  }
  ...
  // alternativer Sessionhandler, CLOSE -->Speichert alle Daten in die DB
  public function close()
  {
    if (!empty($this->sessionID)) {
      $sidData = serialize($this->content);
      $this->db->uquery("UPDATE usersessions SET s_data='" . $sidData . "', s_owner_id=".$this->ownerID.", s_owner='".$this->owner."' WHERE sid='" . $this->sessionID . "'");
    }
  }
  ...
}

Das session->close wird beim destructor aufgerufen.

//EDIT: Habs Problem gefunden. Lag einfach daran, dass ein $db->close noch woanders drin steckte und somit die db vorzeitig schloss. Beim debuggen ist das nicht aufgefallen, aber es funzt jetzte.

trotzdem thx ;).

//EDIT 2: Trotzdem interessiert es mich, wie man ihn dazu bringt die destructor-Reihenfolge der Subklassen zu ändern ;).
tommie-lie
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 4373

Ubuntu 7.10 "Gutsy Gibbon"

BeitragVerfasst: Sa 03.11.07 21:18 
Ach so, ich dachte du meinst eine Vererbungsbeziehung.

user profile iconHeiko hat folgendes geschrieben:
//EDIT 2: Trotzdem interessiert es mich, wie man ihn dazu bringt die destructor-Reihenfolge der Subklassen zu ändern ;).
Anscheinend ist die Bearbeitungsreihenfolge der Destruktoren für verschiedene Objekte nicht definiert. Am besten du nimmst den Java-Weg, auch wenn er eklig ist, und nimmst dispose()-Methoden, die du dann manuell aufrufst. In Java hast du teilweise gar keine andere Chance, weil teilweise Destruktoren nichtmal korrekt aufgerufen werden. Sher schön, wenn man dann serielle Verbindugnen über Bluetooth öffnet und im Destruktor wieder schließt und sich dann fragt, warum man sein Programm nur einmal ausführen kann. ;-)

_________________
Your computer is designed to become slower and more unreliable over time, so you have to upgrade. But if you'd like some false hope, I can tell you how to defragment your disk. - Dilbert
Heiko Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3169
Erhaltene Danke: 11



BeitragVerfasst: Sa 03.11.07 21:33 
user profile icontommie-lie hat folgendes geschrieben:
Ach so, ich dachte du meinst eine Vererbungsbeziehung.

Ne, aber dass du es anders aufgefasst hatte, war an deiner AW abzulesen (des wegen auch der nachträgliche Source ;) ).

Allerdings hatte ich das parent::__destruct trotzdme versucht, denn unter delphi ist es mir erst letztens passiert, dass ich 50% CPU-Auslastung hatte nur weil ich nicht wusste, dass ich etwas überschrieben hab. Da wollte ich da doch sicher gehen. meine Hoffnung war letzt endlich, dass man ihn damit dazu bringt alles zu zerstören und dann erst meinen eigenen Code abzuarbeiten. naja egal - muss ich eben Umwege in Kauf nehmen ;).

@dispose: Gibts das unter php? php.net kennt es zu mindestens nicht (und google gibt auf Anhieb auch nix aus, was ich sprachlich verstehe (kann eben kein japanisch etc :( ) und bei deutsch etc. gibts die Kombi scheinbar nimmer) ;).
tommie-lie
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 4373

Ubuntu 7.10 "Gutsy Gibbon"

BeitragVerfasst: Sa 03.11.07 23:21 
user profile iconHeiko hat folgendes geschrieben:
@dispose: Gibts das unter php? php.net kennt es zu mindestens nicht (und google gibt auf Anhieb auch nix aus, was ich sprachlich verstehe (kann eben kein japanisch etc :( ) und bei deutsch etc. gibts die Kombi scheinbar nimmer) ;).
Naturlich kannst du
ausblenden Quelltext
1:
2:
3:
4:
5:
class miep {
  public function dispose() {
    ...
  }
}
schreiben.
Was anderes ist es in JAva auch nicht. ;-)

_________________
Your computer is designed to become slower and more unreliable over time, so you have to upgrade. But if you'd like some false hope, I can tell you how to defragment your disk. - Dilbert