Man betrachte folgenden Code

session_start();

class myClass {
  public $myString;
}

$myObj = new MyClass();
$myObj->myString = "Hallo Welt";

$_SESSION['store'] = $myObj;

echo $_SESSION['store']->myString; // Hallo Welt

Was fällt hierbei auffälliges auf? Nichts? Korrekt!
Der Code funktioniert wie man es erwartet.

Wird die Klassendefinition nun jedoch in eine eigene Datei ausgelagert und includiert (so wie es sein sollte) und den session_start() weiterhin im Kopf der Datei startet (wie es auch sein sollte), so wird man auf seltsame Probleme stoßen.
Die Ausgabe von echo $_SESSION[‘store’]->myString; ist nämlich plötzlich nicht mehr “Hallo Welt”. Ein Debug-Versuch mit einer Ausgabe von print_r($_SESSION) zeigt uns dann etwas noch viel verwirrenderes! Das Attribut $myString hat sehr wohl noch den Wert “Hallo Welt”, allerdings wird er nicht ausgegeben. Zusätzlich erscheint __PHP_Incomplete_Class Object als Typ des Objects. $myObj ist nach dem Speichern in der Session also nicht mehr vom Typ myClass sondern vom Typ __PHP_Incomplete_Class Object.

Die Erklärung hierzu ist einfacher als gedacht. Alle in der Session abgelegte Daten werden zwischen zwei Seitenaufrufen serialisiert bzw. deserialisiert um sie auf den nächsten Seiten-Request zu transportieren. Das de-serialisieren findet im inneren von session_start() statt. Zu diesem Zeitpunkt liegt die Definition der Ursprungs Klasse myClass noch nicht vor (wird erst später included) und kann daher nicht korrekt deserialisiert werden.

Abhilfe schafft diese kleine FUnktion, welche nach dem session_start und nach dem include sämtlicher Klassen aufrufen werden muss.

function fix(&$object) {
if (!is_object ($object) && gettype($object) == 'object')
return ($object = unserialize(serialize($object)));
return $object;
}

fix($_SESSION['store']);
Categories: PHP

0 Comments

Leave a Reply