copyright (c)  2003   useGroup
PHP

Jochen Stärk
PHP-Tutorial
Sessions

nach untenWofür braucht ein normaler Mensch Sessions?
nach untenWie funktionieren Sessions technisch?
nach untenKonfiguration von PHP: session.auto_start
nach untenDie Konstante SID
nach untenSID in Formularen: session_id
nach untenDie Variable _SESSION
nach untenSitzungen beenden/verlassen
nach untenSitzungen teilweise beenden
nach untenSitzungen starten

Wofür braucht ein normaler Mensch Sessions?

nach obenWofür braucht ein normaler Mensch Sessions? 

HTTP leidet an akuter Amnesie und vergisst leider alles was weiter als ein Formular entfernt ist: Wenn Sie ein Formular submitten, können Sie in der nächsten angezeigten Seite noch sagen, was der Benutzer eingegeben hat, in der übernächsten jedoch nicht mehr. Das ist ziemlich unpraktisch, etwa wenn Sie Assistenten anbieten, auf denen der Benutzer über mehrere Seiten Eingaben machen kann, die erst am Ende in eine Datenbank geschrieben werden sollen oder wenn Sie möchten, dass sich Ihre Benutzer einloggen, und dann auf jeder Seite überprüfen, ob der Benutzer authorisiert ist (obwohl ich da ein angepasstes HTTP-Auth beinahe empfehlen würde).

Theoretisch könnten Sie alle Formulardaten immer in Hidden Inputs in jede Seite schreiben aber das wäre umständlicher als Sessions und erfordert eine Anzahl Hidden Inputs pro Seite die genauso groß ist wie die Anzahl der Inputfelder in Ihrem gesamten Projekt. Wenn Sie diese Lösung noch so programmieren, dass Sie einfach weitere Formularfelder hinzufügen können, ohne die anderen Seiten zu ändern (mit PHP geht das...) haben Sie sich defintiv zu viel Arbeit gemacht.


Wie funktionieren Sessions technisch?

nach obenWie funktionieren Sessions technisch? 

Sie legen einmal eine Session an und erhalten eine ID zurück. PHP speichert dann alle Daten, die unter dieser ID anfallen, zentral und abrufbereit auf dem Server. Der Browser behält sich (nur) seine Session-ID in der Regel in einem Cookie. Ein Problem ist, wenn diese Cookies abgeschaltet sind, würde die Session-ID auf jeder Seite verloren gehen, Sessions wären also vollkommen wirkungslos. Deshalb gibt es die Möglichkeit, die Session ID, SID, auch in (ein einzelnes) Hidden Input einzutragen oder als Parameter bei einem Link zu übergeben. Das heißt, Sie müssen jeden Link, hinter dem Sie die Session noch gebrauchen wollen, so präparieren, dass er die Session ID erhält, falls Sie Cookieablehnende Benutzer nicht vor den Kopf stoßen wollen. Um Session Hijacking zu vermeiden (jemand anders loggt sich mit derselben SID wie ein angemeldeter Benutzer ein), ist die Session ID eine Zufallszahl. Und um Angreifern ihr Handwerk zu erschweren verfällt diese Session ID nach einer angegebenen Laufzeit, außerdem sind Benutzer gehalten, sich auszuloggen (wobei die Session durch den Programmierer als ungültig erklärt wird).


Konfiguration von PHP: session.auto_start

nach obenKonfiguration von PHP: session.auto_start 

Wie auch beim Übernehmen von Formulardaten gibt es bei den Sessions einen Trick, wie Sie es sich einfach machen können: In der php.ini (unter Linux: /etc/php.ini, unter Windows:\windows\system32\php.ini) schalten Sie dazu session.auto_start auf 1 und starten Sie Ihren Apache mit apachectl reload neu. Ob dies auf Ihrem Webserver so gesetzt ist, können Sie praktisch nur über die phpinfo()-Funktion kontrollieren, entweder schreiben Sie sich selbst kurz ein <?php phpinfo(); ?> oder Sie verwenden das Beispiel in Formulardaten übernehmen. Ist session.auto_start nämlich 1, können Sie Sessions einfach verwenden, indem Sie das assoziative Array $_SESSION verwenden.

   <!-- Bitte in die Datei test.php -->
Anzahl Seitenwechsel: <?php
if (!isset($_SESSION["zaehler"])) $_SESSION["zaehler"]=0;
$_SESSION["zaehler"]++;
echo $_SESSION["zaehler"];
?>
<a href="test2.php?<?=SID?>">next</a>
   <!-- Bitte in die Datei test2.php -->
Anzahl Seitenwechsel: <?php
if (!isset($_SESSION["zaehler"])) $_SESSION["zaehler"]=0;
$_SESSION["zaehler"]++;
echo $_SESSION["zaehler"];
?>
<a href="test.php?<?=SID?>">next</a>

   
Beachten Sie, dass die Konstante SID in beiden Dateien im Link angegeben ist. So funktioniert das Beispiel auch mit ausgeschalteten Cookies und zeigt dort dann bei einem Seitenwechsel etwas in der Form test2.php?PHPSESSID=9970ac048cb8b015b5969f1a75e1c4fa in der Adresszeile (und im Link).


Die Konstante SID

nach obenDie Konstante SID 

Die Session-ID können Sie an Links durch die Konstante SID anhängen. Ihr wird nicht, wie bei Variablen, ein Dollarzeichen vorangestellt.

  <a href="test.php?<?=SID?>">next</a>
  
Diese "Konstante" enthält den Namen, wie Session-IDs genannt werden (Standard:PHPSESSID), ein Gleichzeichen und die ID. Sie sollten also an ihren Link vor der SID-Konstante ein ? oder ein & anschließen, je nachdem, ob PHPSESSID der erste oder ein folgender Parameter ist (Man verwendet zum Abgrenzen des Dateinamens vom ersten Parameter ein ? und zwischen den Parametern ein &. Sollten Sie dieses Fragezeichen unterlassen, bekommt der Besucher wohl etwas wie eine File-Not-Found-Fehlermeldung).
  <a href="test.php?action=next&<?=SID?>">next</a>
  


SID in Formularen: session_id

nach obenSID in Formularen: session_id 

Haben Sie ein Formular und möchten nicht, dass durch Drücken des Absenden-Buttons die Session verloren geht, sollten Sie ein verstecktes Eingabefeld mit Namen PHPSESSID einbauen und mit der ID der aktuellen Session belegen. Die Konstante SID ist in dem Fall wertlos, da sie nicht nur die Session-ID speichert, sondern zusätzlich PHPSESSID= vornedran. Interessanter ist in dem Fall wohl die Funktion session_id():

  <form method="post" action="test2.php">
    <input type="hidden" name="PHPSESSID" value="<?=session_id()?>">
    <input type="submit">
  </form>
  
PHPSESSID wird in dem Fall automatisch ausgewertet.


Die Variable _SESSION

nach obenDie Variable _SESSION 

_SESSION ist ein globaler assoziativer Array, die Sie als solche nicht gesondert in Ihrer Funktion zu deklarieren brauchen (keine Angabe von global). Eine Variable speichern Sie in der Session durch Angabe von $_SESSION['variablenname'] = wert;, auslesen tun Sie sie logischerweise mit $auslesewert=$_SESSION['variablenname'].


Sitzungen beenden/verlassen

nach obenSitzungen beenden/verlassen 

Beim ausloggen eines Benutzers sollten Sie PHP die Variablen in dieser Sitzung löschen lassen, damit niemand anders, mit spionierter oder erratener Session-ID, die Session im eingeloggten Zustand kapern kann. Dazu kann ein session_unset() nicht schaden. Der Dokumentation nach solle man bei Verwendung von $_SESSION eher $_SESSION=array(); benutzen, das kann ich aber nicht nachvollziehen, weil session_unset() zumindest in meinem System die gleiche Wirkung zu haben scheint. Allerdings verbietet auch niemand die doppelt-gesichert-hält-besser-Taktik.

  session_unset();
  $_SESSION=array();
  


Sitzungen teilweise beenden

nach obenSitzungen teilweise beenden 

Sie können wie gewohnt mit unset nur ausgewählte Sitzungsvariablen ungültig machen:

    unset ($_SESSION["nameDerZuZerstoerendenVariable"]);
  
Schönen Gruß vom Programmierer: unset ($_SESSION) sollen Sie möglichst vermeiden :-) (siehe Sitzungen beenden)


Sitzungen starten

nach obenSitzungen starten 

Sitzungen starten und beenden sind, zumindest in PHP, zwei grundverschiedene Dinge: Dieselbe Sitzung kann (und muss meistens) häufiger als einmal gestartet, darf und kann allerdings nur einmal beendet werden. Ist session.auto_start in der php.ini aktiviert, wird sie bei Bedarf und so oft als nötig gestartet, beendet wird sie typischerweise nur beim Ausloggen, durch den Programmierer immer extra anzugeben, durch session_unset bzw. $_SESSION=array();. Gestartet im Sinne von session_start() muss die Session immer werden, wenn Sie innerhalb der PHP-Datei verwendet werden soll, also in der Regel in allen PHP-Dateien des Bereichs, in dem Sessions verwendet werden. session_start() ist also eher eine Anmeldung zur Benutzung von Sessions. Existiert noch keine Session-ID, wird diese allerdings beim ersten Session-Start angelegt.

Wie bei header-Funktionen muss session_start() vor jeder Ausgabe (wie echo oder auch nur einem Leerzeichen oder Zeilenvorschub im HTML-Quelltext) erfolgen. Wie erwähnt wird es nur benötigt, wenn session.auto_start=0 ist . Das erste Beispiel für Systeme ohne Session-Auto_start:

<?php session_start(); ?>
<!-- Bitte in die Datei test.php -->
<!-- Keine Kommentare, Leerzeilen oder Leerzeichen - irgendwas - vor dem PHP-Block mit session_start. -->
Anzahl Seitenwechsel: <?php
if (!isset($_SESSION["zaehler"])) $_SESSION["zaehler"]=0;
$_SESSION["zaehler"]++;
echo $_SESSION["zaehler"];
?>
<a href="test2.php?<?=SID?>">next</a>
<?php session_start(); ?><!-- Bitte diese Zeile schon (incl. session_start()) in die Datei test2.php -->
<!-- Keine Kommentare, Leerzeilen oder Leerzeichen - irgendwas - vor dem PHP-Block mit session_start. -->
Anzahl Seitenwechsel: <?php
if (!isset($_SESSION["zaehler"])) $_SESSION["zaehler"]=0;
$_SESSION["zaehler"]++;
echo $_SESSION["zaehler"];
?>
<a href="test.php?<?=SID?>">next</a>

  


copyright (c)  2003   useGroup