PHP: Session-Verwaltung programmieren
Dieser in Internet Professionell veröffentlichte Beitrag zeigt an praktischen Beispielen, wie Sie die Session-Verwaltung von PHP 4 einsetzen.
Die Besucher einer Webseite sind anonym. Allenfalls über die IP lassen sich Daten über die Herkunft eines Benutzers und seine Identität ermitteln. Doch sobald irgendwo ein Proxy sitzt oder ein Router mit IP-Maskierung, ist die Identität dahin.
Schlimmer noch: Nach jedem Seitenabruf wird die Verbindung zwischen Client und Server unterbrochen. Jeder erneute Abruf baut eine neue Verbindung auf. Bei nicht interaktiven Webseiten stört das niemanden. Doch sobald man auch nur grundlegende Funktionen für Online-Shopping oder komfortable Benutzerführung einbauen möchte braucht man irgend etwas, um einen Benutzer auch über mehrere Dokumente hinweg eindeutig zu identifizieren.
Ein Weg führt über Handarbeit mit Cookies oder selbst gebauten URL-Parametern. Der andere Weg ist einfacher: PHP hat ein Session-Management eingebaut, das erlaubt, Variablen über mehrere Web-Seiten hinweg zu verwenden. Je nach Browser-Konfiguration verwendet das Session-Management Cookies oder eine über die Variable SID an die URL angehängte Session ID.
Die Session-IDs wiederum kennzeichnen ein Set an Variablen, das PHP in einem eigens dafür vorgesehenen Verzeichnis speichert.
Dieses Verzeichnis zum Speichern der Sessions wird in der PHP.INI gesetzt. Die zugehörige Variable heißt session.save_path und ist per Default auf /tmp gesetzt. Wenn dieses Verzeichnis öffentlich zugänglich ist, bildet es einen Gefahrenpunkt. Hacker könnten versuchen, sich die Daten aus diesem Verzeichnis zu angeln.
Alternativ können Sie mit der Anweisung session_save_path() während des Programmablaufs ein Verzeichnis bestimmen.
Variablen in einer Sitzung speichern
Ein einfaches Skript zeigt das Prinzip der Session-Verwaltung. Zuerst starten Sie eine neue Sitzung mit session_start(). Hierbei sieht PHP nach, ob bereits eine Sitzung für den Client erzeugt wurde. Falls nein, erzeugt er eine neue. Falls ja, übernimmt er die Daten der bereits existierenden Sitzung.
Um innerhalb der Sitzung eine Variable zu speichern, wird diese registriert. Dies geschieht über session_register(varname). An Stelle von varname steht der Name der Variable, die gespeichert werden soll, in Anführungszeichen.
Ein Beispiel:
<?
session_start();
$name="Hubert Meier";
session_register("name");
?>
<a href=weiter.php>Weiter</a>
Die Variable $name erhält den Wert "Hubert Meier" und wird in der nachfolgenden Zeile registriert. Wichtig: Es wird der Name der Variable registriert, nicht die Variable selbst. session_register($name) wäre also falsch.
Um das Beispiel auszuprobieren, brauchen Sie noch eine Datei weiter.php. Die sieht so aus:
<?
session_start();
echo "Hallo $name<br>";
?>
Beim Klick auf Weiter erscheint dann eine kurze Begrüßung für Hubert Meier.
Wichtig ist, dass auf jeder Seite session_start() aufgerufen wird. Damit werden alle für die Session gespeicherten Variablen als global für das Skript definiert. Die gleiche Aufgabe erledigt session_register(). Diese Funktion impliziert session_start() und holt bei Bedarf ebenfalls alle vorhandenen Variablen in das Skript. Dieses Beispiel registriert zwei Variablen:
<?
session_start();
$name="Hubert Meier";
$strasse="Mühlenweg 5";
session_register("name");
session_register("strasse");
?>
<a href=weiter.php>Weiter</a>
Das Skript weiter.php sieht so aus:
<?
//Nur $name wird registriert
session_register("name");
echo "Hallo $name<br>";
//aber $strasse kommt mit
echo "aus $strasse";
?>
Zusatz-Sitzung
Unabhängig von den Session-Variablen lassen sich Daten auch auf herkömmlichem Weg von Dokument zu Dokument transportieren, zum Beispiel in der URL:
<?
session_start();
$name="Hubert Meier";
session_register("name");
?>
<a href=weiter2.php?wert=10>Weiter</a>
Die Datei weiter2.php sieht so aus:
<?
session_register("name");
echo "Hallo $name<br>";
echo "Per URL übergeben: \$wert=$wert";
?>
Beim Test mit dem Browser erscheinen sowohl der in der Session gespeicherte Namen wie auch die URL übergebene Variable. Falls der Client keine Cookies annimmt, hängt PHP die Session-ID einfach hinter die vom Programmierer definierten Variablen in der URL.
Arrays in Session speichern
Ebenso wie einfache Variablen lassen sich auch Arrays in einer Sitzung speichern. Das Beispiel:
<?
session_start();
$a[]="Hans";
$a[]="Otto";
$a[]="Herbert";
session_register("a");
?>
<a href="arr2.php">Test</a>
Das zugehörige Programm arr2.php liest in diesem Beispiel einen Wert aus dem Array:
<?
session_start();
echo $a[1];
?>
Session-Variablen neu belegen
Ohne Probleme lassen sich im laufenden Betrieb Session-Variablen mit neuen Werten versehen. Die folgenden drei kleinen Beispiele verdeutlichen das Prinzip. Die Datei var1.php:
<?
session_start();
$text="Hallo Erde!";
session_register("text");
echo "Variable \$text ist $text<br>";
?>
<a href="var2.php">Testen</a>
Wichtig ist hier: Wenn die Variable innerhalb der Session zum ersten Mal auftaucht, muss Sie mit session_register() gesetzt werden. Die weiteren Dateien kommen mit session_start() aus.
var2.php sieht so aus:
<?
session_start();
echo "Variable \$text ist $text<br>";
$text="Hallo Mond!";
echo "Variable \$text ist jetzt $text<br>";
?>
<a href="var3.php">Testen</a>
Wichtiges Detail: Die Variable $text darf ihren neuen Wert erst nach session_start() zugewiesen bekommen. Anderenfalls würde die Variable von der mit session_start() eingelesenen Session-Variable überschrieben. Die dritte Datei, var3.php zeigt das Ergebnis:
<?
session_start();
echo "Variable \$text ist $text<br>";
?>
<a href="var1.php">Testen</a>
Anwendungsbeispiel: History-Funktion
Speziell wenn Besucher auf mit Datenbanken generierten Web-Seiten unterwegs sind, ist eine History-Funktion sinnvoll. Die speichert alle besuchten Dokumente in einer Liste und stellt sie per Knopfdruck bereit. Das erleichtert die Navigation auf so einer Seite. Damit die History-Funktion auf allen Dokumenten zur Verfügung steht, packt man sie in eine Header-Datei. Das folgende Beispiel zeigt einen grundlegenden Ansatz, eine solche persönliche History-Funktion zu programmieren.
<? session_start();
session_register(history);
$history[]=$REQUEST_URI;
$history=array_unique($history);
?>
<a href="show_hist.php">History anzeigen</a><br>
Speichern Sie die Datei unter dem Namen hist_head.php, um sie später von beliebigen anderen Dateien aus einzubinden.
Nach dem Start liest das Programm das Array $history ein oder registriert es neu. Danach wird der Inhalt der Server-Variablen $REQUEST_URI als neuer Eintrag dem Array hinzugefügt. Diese Variable enthält den Pfad des gerade aufgerufenen Dokuments relativ zum Root-Verzeichnis des Web-Servers. Eventuelle Parameter sind ebenfalls eingeschlossen. Falls Sie nur die Parameter speichern wollen, verwenden Sie die Server-Variable $QUERY_STRING.
Die Funktion array_unique() wirft alle doppelten Einträge aus dem Array. Wird ein Dokument also mehrmals aufgerufen, erscheint nur der jeweils letzte Aufruf in der Array-Liste. Das spart Platz und erhält die Übersicht.
Die letzte Zeile gibt einen Link auf die History-Liste aus. Diese Datei heißt show_hist.php und sieht so aus:
<? session_start();
echo "Die von Ihnen aufgerufenen Dokumente:<br>";
foreach ($history as $eintrag)
{ echo "<a href=$eintrag>$eintrag</a><br>";
}
?>
Das Array wird in diesem Dokument eingelesen. Allerdings erhält das Array keinen weiteren Eintrag -- das ist im Falle der History-Seite unsinnig.
Der Schleifenbefehl foreach kopiert nacheinander jedes Element des Arrays in eine temporäre Variable $eintrag. Die schreibt einen Hyperlink als Verweis auf die zuvor besuchte Seite.
Um die History auszuprobieren schreiben Sie hist_beisp1.php:
<? include("hist_head.php");?>
<p>Eine Beispielseite.</p>
<a href="hist_beisp2.php">Beispiel 2</a>
und hist_beisp2.php
<? include("hist_head.php");?>
<p>Noch eine Beispielseite</p>
<a href="hist_beisp1.php">Beispiel 1</a>
Die beiden Dateien laden die History-Funktion als Header und zeigen danach einen kurzen Text. Mit einem Klick auf den von der Header-Datei erzeugten Link History anzeigen gelangt der Leser dann zur Anzeige der Liste.
Mit ein wenig Ausbau - etwa dem zusätzlichen Speichern der Titelinformation einer Seite - lässt sich die History-Funktion vor allem auf Servern verwenden, die keine feste Struktur vorgeben.
Mehr dazu:
beispiele.zip
hallo zusammen!
Problem:
Ich habe auf einem Server 2 Verschiedene
Web-Anwendungen.
http://server/tool1/index.php und
http://server/tool2/index.php
In beiden fällen benutze ich den code (siehe unten)
Sobald ich mich in Tool 1 eingeloggt habe
und z. bsp. Tool 2 als 2te seite aufrufe bin ich da auch gleich
eingeloggt *grummel*
Aber es soll sich im Tool 2 extra eingeloggt werden bzw beide
gleichzeitig nutzbar sein.
Denn wenn ich Tool 1 auslogge dann is Tool 2 auch gleich ausgeloggt
:-(
Code:
session_start();
.
.
.
if($loginok){
$_SESSION[login_name] = $name;
$_SESSION[logged_in] = 1;
}
.
.
.
if ($logout ==1){
unset($_SESSION[logged_in]);
unset($_SESSION[logged_name]);
}
.
.
.
---------------------------
Bin für jeden Tipp dankbar.
Grüße!
[coprea | 06.08.2008]
Antworten
Probiers mal so, optimalerweise in einer eigenen eingebundenen Datei
die du dann jedesmal aufrufst wenn du sie brauchst:
if($_SESSION['logged_in']==false) {
$hostname=$_SERVER['HTTP_HOST'];
$path= dirname($_SERVER['PHP_SELF']);
header('Location: http://'.$hostname.($path=='/' ? '' :
$path).'/login.php');
}
Damit leitest du, sollte $_SESSION['logged_in'] auf false oder gar
nicht gesetzt sein, den User automatisch auf deine login-seite weiter.
[thembones | 18.07.2006]
Antworten
Hallo zusammen,
wirklich ein sehr hilfreicher, weil gut verständlicher Artikel. Die
Session-Daten über Seiten hinweg merken klappt schon wunderbar. Aber
ich habe etwas noch nicht ganz verstanden: Ich möchte, dass die Seite
nicht aus dem Stand aufrufbar ist, d.h. wenn der User nicht vorher
einen login-Prozess durchlaufen hat, also die session-Daten nicht
vorhanden sind. Bis jetzt kann ich die Seite immer noch so aufrufen.
Es wäre schön, wenn mir jemand helfen könnte.
[Poxrucker Siegfried | 21.03.2006]
Antworten
Wie viele Datensätze lassen sich in einer Session maximal speichern
(in KB / MB)?
[Marco | 28.09.2005]
Antworten
habe selbiges Problem und keine Möglichkeit die php.ini zu ändern! Die
phpinfo() gibt folgendes von sich:
Directive Local Value Master Value
session.auto_start Off Off
session.bug_compat_42 Off Off
session.bug_compat_warn On On
session.cache_expire 180 180
session.cache_limiter nocache nocache
session.cookie_domain no value no value
session.cookie_lifetime 0 0
session.cookie_path / /
session.cookie_secure Off Off
session.entropy_file no value no value
session.entropy_length 0 0
session.gc_divisor 1000 1000
session.gc_maxlifetime 1440 1440
session.gc_probability 1 1
session.name PHPSESSID PHPSESSID
session.referer_check no value no value
session.save_handler files files
session.save_path /tmp /tmp
session.serialize_handler php php
session.use_cookies On On
session.use_only_cookies Off Off
session.use_trans_sid Off Off
Gibt es eine Möglichkeit trotz dieser Serverseitigen PHP-Einstellungen
dieses Session-Script zu verwenden?
Danke, Tamer
[tamer | 04.07.2005]
Antworten
Wie kommt man den eigentlich an die in der Session gespeicherten
Variablen, wenn register_globals=off steht? Über
$_SESSION['nameDerVariable'] scheint es nicht zu funktionieren.
[Jan Heck | 01.10.2004]
Antworten
Sessions. Werd' ich mir gleich durchlesen und baldigst austesten.
Genau das, das ich schon lange können sollte ;)
[child | 22.09.2004]
Antworten
Vielen Dank!
Dieser Bericht ist super-hilfreich für mich. Danke, dass alle
Funktionen anschaulich an Beispielen erläutert werden!
Wolfgang
[Wolfgang | 19.09.2004]
Antworten
Wolf: danke für das Kompliment. Um alle Fragen zu beantworten fehlt
mir leider manchmal die Zeit. ich bitte dafür um Verständnis.
[Martin Goldmann | 01.09.2004]
Antworten
Schön einfach geschrieben! Sehr verständlich! Wenn der Author etwas
konsequenter die Fragen (alle) beantworten würde.Der Erklär-Stil hat
SelfHTML-Potential! (SelfPHP ist ja leider nicht soo gut) Weiter so,
solche Talente gibt es leider viel zu wenig.
[Der Wolf | 01.09.2004]
Antworten
Vielen Dank!
[anonymous | 16.08.2004]
Antworten
Die Session-ID schleift PHP für Dich mit :-)
[Martin Goldmann | 16.08.2004]
Antworten
schön einfach geschrieben und trotzdem informativ
aber was passiert wenn der client keine cookies annimmt, hab auf
anderen seiten gelesen man müsse dann eine sessionid als parameter
durch die seiten schleifen?
[Fiscsh | 16.08.2004]
Antworten
hi, ich hab mich genau an die syntax von oben gehalten, aber
seltsammer weise passiert bei mir folgendes:
in datei 1 vergibt er die session_id und registriert auch meine
variablen.
in datei 2 findet er auch die richtige session wieder (id ist die
gleiche) aber die registrierten variablen gehen verloren. sie gelten
in datei 2 nicht mehr als registriert und folglich kann man sie auch
nicht abfragen :(
weiß irgend jemand rat ?
mfg soulbinder
ps: register_globals hab ich auf on gesetzt und den server auch
mehrmals neu gestartet! (es funktioniert auch nicht mit dem $_SESSION
array :(
[soulbinder | 06.06.2004]
Antworten
Hallo Kerstin,
danke für das Lob. PHP-Code in Javascript kannst Du schon einbinden,
zum Beispiel:
document.write("<?=$strIrgendwas?>");
Viele Grüße
Martin
[Martin Goldmann | 25.05.2004]
Antworten
Hi, echt ein guter Artikel. Aber ich hab da ein Problem. Ich habe ein
Formular mit ein paar Feldern, deren Eingabe ich bei Ausfuehrung des
Submit-Buttons in einer JavaScript Funktion ueberpruefe. Im Grunde
genommen erscheint eine Meldung, dass keine Eingabe gemacht wurde,
wenn das Feld im Formular nicht ausgefuellt wurde. Nun will ich fuer
den Fall, dass es ausgefuellt wurde, die session-Variable
registrieren, sodass ich auf diese auf der naechsten Seite zugreifen
kann. Gibt es eine Moeglichkeit, diesen php Code in die JavaScript
Funktion einzubinden oder wie kann ich dieses Problem sonst loesen?
Danke und Gruss, Kerstin
[Kerstin | 24.05.2004]
Antworten
Klaufii: Kann es sein, dass auf dieser Seite ein Formular ist? Wenn
ja, dann will der Browser beim Aktualisieren der Seite ein ganz ein
schlauer sein und bietet Dir an, nochmals die Formulardaten zu senden.
Insofern ist ein simpler Reload nicht unbedingt zu empfehlen.
[Martin Goldmann | 24.05.2004]
Antworten
Hi, Leute
Ich habe da so ein Problem. Ich will eine php seite aktualisieren.
wenn ich dazu den reload verwende dann kommt so ne messagebox von
wegen senden.(hab das nicht so genau in kopf) aber ich hoffe ihr wisst
was ich meine. wollte nun wissen, ob man es mit einer session umgehen
kann bzw. wie man das überhaupt so machen kann das bei aktualisieren
der seite diese meldung nicht kommt. danke euch allen schon im voraus.
[Klaufii | 21.05.2004]
Antworten
Hallo -
tolle Seite - nur ist es ein frommer Wunsch, dass PHP, wenn der
Browser keine Cookies unterstützt, die Sessionnummer automatisch an
die URL anhängt .
[Stefan Lehmann | 08.05.2004]
Antworten
@vash: Ja, stimmt. Der Artikel ist allerdings schon ziemlich alt und
basiert noch auf PHP3-Erfahrungen. $_SESSION wurde ja erst mit PHP
4.1.0 eingeführt, die Default-Einstellung register_globals = off kam
mit PHP 4.2.0. Und für den Fall register_globals = off braucht man
dann ja auf jeden Fall $_SESSION.
[Martin Goldmann | 15.04.2004]
Antworten
Es waere sinnvoller fuer die Sessionvariablen $_SESSION[] zu benutzen.
[.vash | 15.04.2004]
Antworten
Hallo Manuela,
der Grund dafür ist, dass das Array $history offenbar nicht existiert
oder leer ist. Forsche doch da mal weiter.
Viele Grüße
Martin
[Martin Goldmann | 15.04.2004]
Antworten
Hallo!
Ich habe folgendes Problem bei dem Aufruf von foreach:
Warning: Invalid argument supplied for foreach() in
c:\programme\apache group\apache\htdocs\ins\admin\show_hist.php on
line 3
Woran kann das liegen?
Danke.
[Manuela | 15.04.2004]
Antworten
Wenn ich das Problem richtig verstanden habe könnte das eventuell
helfen:
Man schreibt Seite für Seite in eine Mysql Tabelle die Werte und die
Zeit bzw.ID so muß man in der URL die zur letzten Seite führt einfach
die ID der Seite
[Nolf Herb | 03.02.2004]
Antworten
Hallo,
dieser Artikel ist hervorragend. Danke. Trotzdem noch eine Frage: Wenn
ich damit einen Zurück-Button belegen will, muss ich den letzten
Eintrag herauslesen weil der letzte Eintrag die Seite speichert von
der der User gekommen ist. Aber wie kann man das lösen? Hat jemand
darauf eine Antwort?
[Rolf Oppermann | 16.01.2004]
Antworten
Super Artikel. Wollte schon fast aufgeben, mit SESSIONS zu arbeiten.
Jetzt funzt es wunderbar !
[André | 22.12.2003]
Antworten
Hi,
das liegt daran, dass schon irgendeine andere Ausgabe vor dem
session_start() gemacht wurde. Sobald Du zum Beispiel mit
echo "blabla"
einen Text ausgibst, sendet PHP schon einen Header. Daher die "already
sent"-Meldung.
Eventuell hast Du auch Dein <? für den PHP-Code-Beginn nicht in die
erste Zeile an die erste Stelle gesetzt. Dann wird schon ein
Leerzeichen geschickt. Und auch das kann dieses Problem verursachen.
Viele Grüße
Martin
[Martin Goldmann | 18.12.2003]
Antworten
Ich bekomme beim Aufruf von session_start(); diesen Fehler. Und nun?
Warning: Cannot send session cookie - headers already sent by (output
started at c:\cd\web-projekte\suo\login2.php:10) in
c:\cd\web-projekte\suo\login2.php on line 11
Danke für die schnelle Antwort
[PinkiJoe | 18.12.2003]
Antworten




