Verwendung von Sessions in PHP
Artikel erschienen in Swiss IT Magazine 2001/32
Wer in PHP mehr als ein Skript für eine Webseite programmiert, kennt sicher das Problem: Geht der Anwender von einer Seite zur nächsten, sind alle Variablen für das nächste Skript verloren, es sei denn, sie wurden über ein Formular oder mit der URL zur nächsten Seite übertragen. Diese Übertragung ist jedoch nicht nur lästig, sondern auch fehleranfällig und unsicher. URL-Daten können leicht manipuliert werden, und auch Hidden-Felder in Formularen sind vor Manipulationen nicht sicher.
Der Grund für diesen Zustand ist, dass HTTP ein Protokoll ohne Status ist. Während ein Programm auf dem eigenen PC immer "weiss", welcher Benutzer das Programm gerade bedient, kennt der Webserver den Benutzer nicht. Daher muss sich der Entwickler darum bemühen, den Anwender für das Skript erkennbar zu machen.
Um nun Daten über mehrere Seiten hinweg zu speichern, ist eine Session in PHP ideal geeignet. Das Grundprinzip ist ebenso einfach wie genial: Alle Daten, die über mehrere Seiten gespeichert werden sollen, werden auf der Festplatte des Webservers zwischengespeichert. Für jeden Anwender wird dabei eine eigene Datei verwendet. Damit der Webserver die Daten dem richtigen Anwender wieder zuordnen kann, wird eine Session-ID erzeugt, mit der sich die entsprechende Datei wiederfinden lässt. Nun muss nur noch diese eine Session-ID von Seite zu Seite übergeben werden.
Damit hat sich im Prinzip nicht sehr viel geändert, die Anforderungen sind jedoch einfacher geworden. Statt einer Reihe von Daten muss nur noch eine ID von Seite zu Seite gegeben werden. Diese ID ist so gestaltet, dass sie nur schwer manipulierbar ist. Damit ist sichergestellt, dass niemand auf die Daten eines anderen zugreifen kann, der zur gleichen Zeit online ist. Da auch keine einzelnen Daten mehr übertragen werden müssen, können diese auch nicht mehr zwischen den Seitenabrufen manipuliert werden.
Mit session_start() wird die Session begonnen, session_register() registriert die Variablen "s_username" und "s_age" für die aktuelle Session. Die Funktion session_register() ruft implizit session_start() auf; es schadet allerdings nicht, in jedem Skript session_start() als erste Zeile einzufügen, wenn eine Session verwendet werden soll.
Wichtig ist ausserdem, dass session_start() aufgerufen wird, noch bevor irgendwelche HTML-Ausgaben gemacht werden, da die Funktion bestimmte Header an den Browser versendet. Die Funktion muss also noch vor dem ersten html-Tag und auch noch vor dem doctype-Tag stehen.
Es ist auch eine gute Gewohnheit, Session-Variablen speziell zu kennzeichnen, wie es hier mit dem vorangestellten "s_" erfolgt. Damit lassen sich diese dann von den normalen "flüchtigen" Variablen gut unterscheiden. Bei Verwechslungen kommt es meist zu Fehlern, die nur schwer zu finden sind.
Wurden die Werte "username" und "age" im Formular eingetragen, so werden diese sogleich den entsprechenden Session-Variablen zugewiesen. Geht man nun über einen Link zur nächsten Seite weiter.php, so stehen diese schon zur Verfügung:
Auch hier muss wieder session_start() an erster Stelle aufgerufen werden. In der Einleitung wurde erklärt, dass eine Session-ID von Seite zu Seite übertragen wird. Beim Übergang von Formular zu Formular wurde diese jedoch im Code nicht erwähnt. PHP verwendet hier eine Reihe von Automatik-Funktionen, die eine Weitergabe der Session-ID veranlassen.
Standardmässig wird die Session-ID in einem Cookie gespeichert. Ist dieses Cookie noch nicht vorhanden (das heisst, die Session wird auf der Seite zum ersten Mal verwendet), so wird es durch die Funktion session_start() automatisch angelegt.
Bei Formularen wird per GET oder POST automatisch die Session-ID mit übergeben. PHP verändert den HTML-Code entsprechend, so dass dies gewährleistet ist. Am einfachsten sieht man dies, indem man sich den erzeugten HTML-Code des beschriebenen Beispiels einmal anschaut:
Der Standardname der Session-ID ist "PHPSESSID". Diese Variable wird im Formular als verstecktes Feld (hidden) beim Abschicken übergeben. Ausserdem ändert PHP jeden HTML-Link so ab, dass PHPSESSID als Parameter mit der passenden Session-ID übergeben wird. Diese Fallback-Strategie wird jedoch nur dann verwendet, wenn kein Cookie zur Verfügung steht.
Wird die Seite mit "Reload" neu aufgerufen, verschwinden diese Session-IDs wieder im HTML, weil nun das gesetzte Cookie bereits vorhanden ist. Wird die Seite zum ersten Mal aufgerufen, ist das Cookie noch nicht gesetzt, so dass PHP hier automatisch das Fallback verwendet. Dies lässt sich leicht testen, indem die Cookies des Browsers abgeschaltet werden. In diesem Fall werden die Session-IDs im HTML-Code immer eingetragen.