OOP: Lebensdauer von Objekten

Cathness

Grünschnabel
Hallo,

meine Frage, die ich noch nirgendwo zufriedenstellend beantwortet gefunden habe, betrifft die Lebensdauer der OOP-Objekte in PHP. :confused:

Bei anderen Programmiersprachen ist die Sache klar: die Objekte bleiben so lange bestehen, solange Referenzen auf die Objekte bestehen. Bei PHP sehe ich da Probleme, die mich vermuten lassen, daß die Lebensdauer der Objekte entweder an die Dauer des aufrufenden Skripts oder an die Session gebunden ist.

Wer kann mir das beantworten und begründen?


Viele Grüße
C.
 
Objekte werden automatisch zerstört, wenn ihr Gültigkeitsbereich („scope“) verlassen wird. Der Gültigkeitsbereich kann z.B. das Innere einer Funktion sein:
PHP:
<?php

class Foo
{
	function __construct()
	{
		echo 'Instanz erzeugt!'."\n";
	}

	function __destruct()
	{
		echo 'Instanz zerstört!'."\n";
	}
}

function bar()
{
	$f = new Foo();
}

echo '1. Aufruf:'."\n";
bar();
echo '2. Aufruf:'."\n";
bar();

?>

Ausgabe:
Code:
1. Aufruf:
Instanz erzeugt!
Instanz zerstört!
2. Aufruf:
Instanz erzeugt!
Instanz zerstört!
In einer Funktion erzeugte lokale Objekte werden also beim Verlassen der Funktion automatisch zerstört. (Der genaue Zeitpunkt des Destruktoraufrufs kann allerdings nicht vorausbestimmt werden.)
 
Also ist das Verhalten von PHP in diesem Punkt wie das einer jeden OOP-fahigen Sprache?

D.h., solange der scope und die Referenzen bestehen bleiben, bleibt das Objekt (und die dazugehörige Klasse) erhalten, auch wenn das Skript abgelaufen ist?

Wann endet dann die Lebensdauer entgültig, wenn der Benutzer die Seite/das Skript verläßt, sprich, der Client vom Server getrennt wird? Mit der Session?

Und wie funktioniert das mit der garbage collection?


Fragen über Fragen...

Gruß
TT
 
Cathness hat gesagt.:
Also ist das Verhalten von PHP in diesem Punkt wie das einer jeden OOP-fahigen Sprache?
Ja, in gewisser Weise schon.

D.h., solange der scope und die Referenzen bestehen bleiben, bleibt das Objekt (und die dazugehörige Klasse) erhalten, auch wenn das Skript abgelaufen ist?
Nein! Jedes Objekt wird spätestens unmittelbar nach der Abarbeitung des Skripts zerstört (denn dann wird der Scope verlassen). Wo und warum sollten die Objekte auch (automatisch) zwischen einzelnen Skriptaufrufen gespeichert werden?

Und wie funktioniert das mit der garbage collection?
Was willst du denn darüber wissen?
 
Danke schonmal für Deine Antworten.

Meine Frage dreht sich um folgendes:

Wenn ich mit PHP objektorientiert programmiere, möchte ich, daß meine Objekte zwischen den einzelnen Seitenaufrufen erhalten bleiben. Z.B. erstellt/enthält ein PHP-Skript ein Objekt (nehmen wir mal das einfache Beispiel des Warenkorbs, das einen Artikel enthält), das im nächsten PHP-Skript, sagen wir auf der Seite warenkorb.php, noch bestehen soll.

Auch wenn ich sowohl den Warenkorb als auch die Artikel als Objekte behandele, möchte ich wissen, was der beste Weg ist, die Objekte bestehen zu lassen. Rufe ich z.B. ein einem PHP-Skript eine main()-Methode einer Applikationsklasse auf (wie man es von Java o.ä. kennt), die bestehen bleibt, auch wenn das aufrufende Skript aufhört zu existieren?

Das scheint für mich eine sehr grundlegende Implementierung von OOP zu sein, bin aber dennoch nicht sicher, ob OPP in PHP auf diese Weise funktioniert.
 
Matthias Reitinger hat gesagt.:
Um Objekte über mehrere Aufrufe hinweg zu erhalten, sollte man Sessions verwenden.
Cathness hat gesagt.:
Bei PHP sehe ich da Probleme, die mich vermuten lassen, daß die Lebensdauer der Objekte entweder an die Dauer des aufrufenden Skripts oder an die Session gebunden ist.

:(
Das hatte ich befürchtet.

Aber lassen sich in Sessions auch Klassen und Instanzen speichern?
Ich sehe sonst das Problem, daß ich bei jedem PHP-Skript, das ich aufrufe, die ganze Chose neu erstellen muß, und ich kann mir nicht vorstellen, daß das nicht erheblich zu Lasten der Performance geht.

*grübel grübel*

Gruß
C.
 
^^

Tja ... in dieser Hinsicht muss man sich in PHP etwas umgewöhnen. Will man Elemente über mehrere Seiten verfügbar machen, muss man sie bei jeden neuen Seitenaufruf neu erzeugen. Die schnellste Variante ist, wie schon erwähnt, die Session Variante. Du könntest natürlich auch eine DB verwenden.

Aber so schwierig wird das ganze ja nicht. In deiner Warenkorbklasse muss eine Methode hinein, welche die Daten aus der Session entnimmt. Da du bei einem Neuaufruf des Scripts auch das Objekt neu erzeugen musst, kannst du ja einfach im Konstruktor prüfen, ob die Session Warenkorbeinträge enthält und das ganze dann mit den Daten initialisieren.

Soweit ich weiß kannst du Objekte auch serialisiert in einer Session speichern. Ich hab aber so im Hinterkopf, dass dann nicht alle Methoden mit gespeichert werden, sondern nur die Werte ... Es ist auf jeden Fall nicht trivial, ein Objekt über mehrere Seiten verfügbar zu machen.
ABER: Da es von PHP sowieso wieder initialisiert werden muss (du gibst ja nur die Daten weiter), ist es von der Performance her egal. PHP zerstört beim beenden eines Scripts alle Klasseninstanzen, so dass es diese Instanzen (auch wenn der Inhalt gespeichert wurde) wieder neu erzeugen muss. Dann kannst du die Objekte auch gleich neu erzeugen.

Aber es ist wirklich manchmal etwas stressig mit PHP. Ich wünschte ab und zu auch, dass man damit einfach Applikationen, die wie Desktopapplikationen funktionieren, programmieren könnte. (Und ich meine damit nur mit PHP, also nicht das vortäuschen mit AJAX <-- trotzdem tolle Sache :-) )

Ciao, Jörg
 
Zuletzt bearbeitet:
F.o.G. hat gesagt.:
Soweit ich weiß kannst du Objekte auch serialisiert in einer Session speichern. Ich hab aber so im Hinterkopf, dass dann nicht alle Methoden mit gespeichert werden, sondern nur die Werte ... Es ist auf jeden Fall nicht trivial, ein Objekt über mehrere Seiten verfügbar zu machen.
So schwer ist das nicht :)

myclass.inc.php
PHP:
<?php

class MyClass {
	private $name;

	function __construct($name) {
		$this->name = $name;
	}

	function getName() {
		return $this->name;
	}
}

?>

page1.php
PHP:
<?php

require('myclass.inc.php');

$obj = new MyClass('foobar');

session_start();
$_SESSION['obj'] = $obj;

?>
<a href="page2.php">weiter</a>

page2.php
PHP:
<?php

require('myclass.inc.php');

session_start();
$obj = $_SESSION['obj'];

echo $obj->getName(); // gibt foobar aus

?>

Für den Programmierer ist es also egal, ob man eine Zeichenkette, eine Ganzzahl oder eben eine Klasseninstanz in einer Session speichert. Um die nötige Serialisierung/Deserialisierung kümmert sich PHP von alleine. Wichtig ist dabei nur, dass beim Deserialisieren die Klassendefinition verfügbar sein muss (hier durch ein [phpf]require[/phpf] gelöst).
 
Zurück