echo $begrüßung;
$Class1 = new B();
$Class1->Value = 3;A::SetObject($Class1, 100);
echo $Class1->Value; // Wie erwartet, 100
Ja, aber: $Class1 ist nun ein neues Objekt und nicht mehr das, was du vorher mit new B() erzeugt hast. Füge debug_zval_dump($Class1); vor und nach der Zeile A::SetObject... ein. Dann siehst du #1 und #2.
$Class1->Test();
echo $Class1->Value; // wie befürchtet immer noch 100
Innherhalb der Methode Test() hast du ein $this, das eine Referenz auf das aktuelle Objekt (#2) ist. Durch dein SetObject() erreichst du, dass $this nun eine Referenz auf das neue Objekt #3 ist. Doch $Class1 bekommt davon nichts mit, denn das referenziert immer noch auf #2.
Gespickt mit Testausgaben sieht der Code so aus:
class A {
static function SetObject(&$Object, $Value) {
echo 'Object-1: '; debug_zval_dump($Object);
$Test = new B();
$Test->Value = $Value;
echo 'Test: '; debug_zval_dump($Test);
$Object = $Test;
echo 'Object-2: '; debug_zval_dump($Object);
}
}
class B {
public $Value;
public function Test() {
echo 'this-1: '; debug_zval_dump($this);
A::SetObject($this, -1);
echo 'this-2: '; debug_zval_dump($this);
}
}
$x = $Class1 = new B();
$Class1->Value = 3;
echo 'Class1-1: '; debug_zval_dump($Class1);
A::SetObject($Class1, 100);
echo $Class1->Value; // Wie erwartet, 100
echo 'Class1-2: '; debug_zval_dump($Class1);
$Class1->Test();
echo $Class1->Value; // wie befürchtet immer noch 100
echo 'Class1-3: '; debug_zval_dump($Class1);
Nachdem $Class1 durch #2 überschrieben wurde, verweist nichts mehr auf #1. Das Objekt wird aufgeräumt und die Nummer 1 wiederverwendet. Das stört etwas die Nachvollziehbarkeit, weswegen ich mit $x eine Referenz auf #1 erzeugt habe, die #1 leben lässt. Somit bekommen wir #3 und keine zweite #1 in den Ausgaben von debug_zval_dump().
Also will ich (am Ende des Scripts) den Status verschiedener Objekte in einer Session speichern, damit ich diese beim nächsten Aufruf widerherstellen und mit den alten Werten weiter arbeiten kann.
Ich denke, du kannst dafür eine Registry einsetzen, die die verschiedenen Objekte an einer zentralen Stelle zusammenfasst. Diese Registry kannst du am Ende der Session übergeben und sie am Anfang aus ihr wiederherstellen. Eine Implementation einer Registry gibt es im Zend Framework.
Du erstellt deine Objekte wie üblich, arbeitest ganz normal mit ihnen und meldest sie lediglich in der Registry an. Das kann gleich nach der Instantiierung erfolgen. Wenn du keine Kopfstände mit ihnen machst, bei denen dir die Referenzen auf die Objekte verlorengehen, denke ich, ist das eine klare und überschaubare Lösung.
Zu beachten ist, dass PHP5 generell Referenzen bei Objekten verwendet. Das kann nachteilig sein, wenn das Objekt in der Session sitzt und mit Referenzen darauf an anderen Stellen gearbeitet wird, da ein Zugriff auf eine Session-Variable aufwendiger ist als bei einer normalen Variable. Bei spärlichem Gebrauch fällt dies aber praktisch kaum ins Gewicht. Gegebenenfalls musst du die Registry aus der Session clonen, wobei du sicher Object cloning beachten musst, sonst hast du wegen der "shallow copy" zwar einen clone der Registry, aber weiterhin Referenzen der darin abgelegten Objekte.
echo "$verabschiedung $name";