Statische Klassenvariable und Sessions

Gibt es einen Weg, den Wert statischer Klassenvariable in einer
Session zu speichern?

Konkret geht es mir darum, eine Singleton-Klasse zu implementieren,
von der über mehrere Skripte hinweg nur ein Objekt erzeugt werden
soll.

Roland
Roland Smiderkal [ So, 02 Dezember 2007 11:36 ] [ ID #1884109 ]

Re: Statische Klassenvariable und Sessions

Roland Smiderkal wrote:
> Gibt es einen Weg, den Wert statischer Klassenvariable in einer
> Session zu speichern?

Ich verstehe nicht ganz wo Du ein Problem siehst:
$_SESSION['Abc'] = MyClass::Abc;

> Konkret geht es mir darum, eine Singleton-Klasse zu implementieren,
> von der über mehrere Skripte hinweg nur ein Objekt erzeugt werden
> soll.

und was hat das mit statischen Klassenvariablen zu tun außer das die
Singletón Instanz darüber gehalten wird?

$_SESSION['MyClass'] = MyClass::GetInstance();

Wenn die je nach notwendigkeit __sleep und/oder __wakeup implementierst
und ggf. nen sessionhandler kannst Du das so tun.

Oder worauf willst Du hinaus? (Evtl. Frage präzisieren)

MfG, Ulf

--
_,
_(_p> Ulf [Kado] Kadner
\<_)
^^
Ulf Kadner [ So, 02 Dezember 2007 11:54 ] [ ID #1884110 ]

Re: Statische Klassenvariable und Sessions

Ulf Kadner schrieb:
>> Gibt es einen Weg, den Wert statischer Klassenvariable in einer
>> Session zu speichern?
>
>Ich verstehe nicht ganz wo Du ein Problem siehst:
>$_SESSION['Abc'] = MyClass::Abc;

Ich habe mich schlecht ausgedrückt. Ich wollte, dass die statische
Klassenvariable *implizit* gespeichert wird, wenn ich das Objekt
serialisiere.

>> Konkret geht es mir darum, eine Singleton-Klasse zu implementieren,
>> von der über mehrere Skripte hinweg nur ein Objekt erzeugt werden
>> soll.
>
>und was hat das mit statischen Klassenvariablen zu tun außer das die
>Singletón Instanz darüber gehalten wird?

Genau das ist das Problem. Ich wollte folgendes machen:

In page1.php:

$abc = MyClass::getInstance();
$_SESSION['abc'] = serialize($abc);

Und in page2.php:

$abc = unserialize($_SESSION['abc']);

// irgndwo in der gleichen Datei

$xyz = MyClass::getInstance();

In page2.php ist die statische Klassenvariable nicht mehr gesetzt.

>Wenn die je nach notwendigkeit __sleep und/oder __wakeup implementierst
>und ggf. nen sessionhandler kannst Du das so tun.

An __sleep()/__wakeup() hab ich gar nicht gedacht. Ich habe folgendes
versucht:

public function __sleep()
{
if (self::$instance !== NULL) {
$local_instance = self::$instance;
self::$instance = NULL;
$_SESSION['rfilm_instance'] = serialize($local_instance);
}
}

public function __wakeup()
{
if (self::$instance === NULL) {
if (isset($_SESSION['rfilm_instance'])) {
self::$instance = unserialize($_SESSION['rfilm_instance']);
}
}
}

Das schaut fürchterlich aus und funktioniert nicht.

Grüße
Roland
Roland Smiderkal [ So, 02 Dezember 2007 14:20 ] [ ID #1884112 ]

Re: Statische Klassenvariable und Sessions

Roland Smiderkal schrieb:
> Ulf Kadner schrieb:

>>> Konkret geht es mir darum, eine Singleton-Klasse zu implementieren,
>>> von der über mehrere Skripte hinweg nur ein Objekt erzeugt werden
>>> soll.

>> und was hat das mit statischen Klassenvariablen zu tun außer das die
>> Singletón Instanz darüber gehalten wird?

> Genau das ist das Problem. Ich wollte folgendes machen:

> In page1.php:
>
> $abc = MyClass::getInstance();
> $_SESSION['abc'] = serialize($abc);

Du brauchst das Objekt nicht serialisieren, wenn du es in die Session
steckst. Dann kannst du ja gar nicht mehr vernüftig damit arbeiten.

$_SESSION['abc'] = MyClass::getInstance();

> Und in page2.php:
>
> $abc = unserialize($_SESSION['abc']);

$_SESSION['abc']->machWas();

> // irgndwo in der gleichen Datei
>
> $xyz = MyClass::getInstance();
>
> In page2.php ist die statische Klassenvariable nicht mehr gesetzt.

Ja, die werden ja auch nicht mit serialisiert. Du musst die Instanz
direkt in der Session speichern, d.h. schon in getInstance(). Ansonsten
musst du in allen Scripten etwas wie

if(!isset($_SESSION['abc'])) {
$_SESSION['abc'] = MyClass::getInstance();
}

$_SESSION['abc']->machWas();

verwenden, anstelle des einfachen MyClass::getInstance().

>> Wenn die je nach notwendigkeit __sleep und/oder __wakeup implementierst
>> und ggf. nen sessionhandler kannst Du das so tun.

> An __sleep()/__wakeup() hab ich gar nicht gedacht. Ich habe folgendes
> versucht:
>
> public function __sleep()
> {
> if (self::$instance !== NULL) {
> $local_instance = self::$instance;
> self::$instance = NULL;
> $_SESSION['rfilm_instance'] = serialize($local_instance);
> }
> }
>
> public function __wakeup()
> {
> if (self::$instance === NULL) {
> if (isset($_SESSION['rfilm_instance'])) {
> self::$instance = unserialize($_SESSION['rfilm_instance']);
> }
> }
> }
>
> Das schaut fürchterlich aus und funktioniert nicht.

__wakeup() und __sleep() werden automatisch ausgeführt, wenn
unserialize()/serialize() ausgeführt wird. Da du aber die Funktionen
erst in den magischen Methoden aufrufst, kann das nicht funktionieren.

Du könntest auf den statischen Member verzichten, und etwas machen wie:

class SessionSingleton {
private function __construct() {
}

public static function getInstance() {
if(!isset($_SESSION['instance'])) {
$_SESSION['instance'] = new SessionSingleton();
}

return $_SESSION['instance'];
}
}

session_start();

$i = SessionSingleton::getInstance();

Das macht im Prinzip schon das was du willst, allerdings kannst du so
nicht wirklich sicherstellen, das nur eine Instanz erzeugt wird. Wenn du
zum Beispiel

$i = SessionSingleton::getInstance();
$_SESSION['instance'] = null;
$i = SessionSingleton::getInstance();

ausführst, hast du zwei Instanzen erzeugt. Das kannst du allerdings auch
bei deiner __wakeup()/__sleep() Lösung nicht sicherstellen.

--
"Faulheit ist die Wurzel allen Fortschritts!"
(Inhalt eines Knallbonbons, 2002)
dafox [ So, 02 Dezember 2007 14:51 ] [ ID #1884115 ]

Re: Statische Klassenvariable und Sessions

Thomas Hamacher schrieb:

>Du brauchst das Objekt nicht serialisieren, wenn du es in die Session
>steckst. Dann kannst du ja gar nicht mehr vernüftig damit arbeiten.

Da hab' ich mich verrannt. Als mein erster Versuch nicht funktioniert
hat, hab ichs mit dem Serialisieren versucht.

>__wakeup() und __sleep() werden automatisch ausgeführt, wenn
>unserialize()/serialize() ausgeführt wird. Da du aber die Funktionen
>erst in den magischen Methoden aufrufst, kann das nicht funktionieren.

Mein Gedankengang war, dass durch das äußere Serialisieren das innere
Serialisieren angestossen wird. Irgendwie war ich "on tilt".

>Du könntest auf den statischen Member verzichten, und etwas machen wie:
>
> [...]
>
>Das macht im Prinzip schon das was du willst, allerdings kannst du so
>nicht wirklich sicherstellen, das nur eine Instanz erzeugt wird.

Das ist genau das was ich wollte, Danke

Roland
Roland Smiderkal [ So, 02 Dezember 2007 17:56 ] [ ID #1884117 ]
PHP » de.comp.lang.php.misc » Statische Klassenvariable und Sessions

Vorheriges Thema: str_replace wirkt nicht?
Nächstes Thema: Variable Aufrufe statischer Methoden