Werbung einblenden Werbung ausblenden


Home / Tutorials / PHP Handbuch / Cookies und Sessions


Cookies und Sessions
Setzen eines Cookies
Zwei Cookies auf einmal setzen

Auslesen eines Cookies
Werte eines Cookies
Temporäre Cookies
Einen Array in einem Cookie speichern
Session
Sessions in der php.ini aktvieren

Cookies und Sessions

Cookies sind Informationen, die auf der Festplatte desjenigen abgelegt werden, der die Seite aufruft. Sinnvoll ist sowas, wenn man wissen will, wie oft der User, eigentlich der Computer, schon auf der Seite war, wann er das letzte mal da war, ob er bereits registriert ist etc. etc. Auf der Seite des Anbieters kann man diese Informationen nicht speichern, weil es ja nichts gibt, was den Client eindeutig identifiziert. Man könnte höchstens an die IP Adresse denken, aber die ist ja meistens dynamisch, wird also jedesmal neu vergeben, wenn man sich ins Internet einwählt. Wer diese Zeilen liest, der kennt die Diskussion um Cookies. Diese Diskussion hat dazu geführt, dass viele Leute Cookies deaktiviert haben. Cookies sind Textdateien und keine ausführbaren Dateien. Cookies wünscht man sich am häufigsten in Verbindung mit e-commerce Lösungen, also z.B. Shops. Bestellt der User mehrere Produkte von unterschiedlichen HTML-Seiten, so muss es für den Fremdrechner möglich sein, die verschiedenen Bestellvorgänge ein und derselben Person bzw. Rechner zuzuordnen. Das kann er nur, wenn bei jedem Aufruf irgendetwas mitgeliefert wird, was den Besteller eindeutig identifiziert. Setzt man zu Beginn, also z.B. wenn er den Shop betritt, einen Cookie und schreibt da irgendetwas rein, was den User identifiziert, dann kann man diesen Wert immer wieder mitliefern. Dies erlaubt es dem Server, zu erkennen, welche Bestellvorgänge zu wem gehören. Es sei nicht verschwiegen, dass es zu diesem Verfahren Alternativen gibt. Eine Alternative wäre, den Warenkorb in einem JavaScript komplett clientseitig zu halten und erst wenn tatsächlich bestellt wird, alle Informationen auf einen Husch zu übermitteln. Denkbar ist auch, via

<input type=hidden name=irgend_was_identifizierendes>

eine User-Kennung von Seite zu Seite mitzuschleppen. Darüber zu sinnen, welche Alternative die beste ist, bleibt jedem selber überlassen. Die einfachste Möglichkeit einen Cookie zu setzen, sieht so aus.

Setzen eines Cookies

<?
setcookie("Name","Andres Ehmann",Time()+1200);
print "Keks wurde gesetzt";
?>

Wie der Cookie dann konkret im Rechner abgespeichert wird, ist abhängig vom Browser. Mit dem Internet Exploder wird der Skript in das Verzeichnis c:/windows/cookies ein File mit dem Namen name_des_rechners@irgendeine_domain.txt geschrieben. Für alle Cookies einer Domain wird eine Cookie Datei gebildet. Öffnet man diese, sieht man etwas in der Art.

Name
Andres+Ehmann
127.0.0.1/
1024
667801216
34459479
2453922688
29532697
*


(Genau genommen sieht man es in einer Zeile, anstatt des \r\n steht eine Hieroglyphe. Kopiert man es aber in wordpad,sieht es aus wie oben.) Die einzelnen Werte haben nun folgende Bedeutung. Name ist der Name der Variablen. Diese hat den Wert Andres Ehmann. Über den Namen können wir den Wert Andres Ehmann nachher wieder rausfischen. Die 127.0.0.1 ist die Domain, die den Cookie generiert hat. Die 1024 bedeutet, dass es sich um einen Cookie handelt, der nicht von einer ssl (secure socket layer) Verbindung eingerichtet wurde, wenn dem so wäre, stünde da 1025. Die nächste Zahl gibt an, wie lange der Cookie gültig ist, die übernächste Zahl, nummeriert die Cookies. Setzt man zwei Cookies, macht also sowas.

Zwei Cookies auf einmal setzen

<?
setcookie("Name","Andres Ehmann",Time()+1200);
setcookie("Hobby","schwimmen",Time()+1200);

print "Keks wurde gesetzt";
?>

dann erhält man sowas

Name
Andres+Ehmann
127.0.0.1/
1024
4067866624
34459481
1233153504
29532701
*
hobby
schwimmen
127.0.0.1/
1024
2362833920
34459480
1233153504
29532701
*

Der dritte Parameter der Funktion setcookie ist eine Zeitangabe. Sie bestimmt, bis wann der Cookie gültig ist. Hierbei ermittelt die Funktion Time(), die Anzahl der Sekunden, die seit dem 1.1.1970 vergangen ist. Zu dieser Zeit werden 1200 Sekunden hinzuaddiert. Das ist dann das Verfallsdatum des Cookies. Schauen wir uns nochmal an, was bei Netscape passiert. Bei Netscape werden die Cookies im Ordner ......./Netscape/users/default/cookies.txt gespeichert, also alle Cookies in einer Datei. Für den Cookie oben wird eine solche Zeile hinzugefügt.

127.0.0.1 FALSE FALSE 1039731013 Name Andres+Ehmann

Hierbei sind die letzten beiden Werte wieder selbsterklärend. Für Leerzeichen werden, ähnlich wie bei der Generierung des Query Strings, Formulareingaben auswerten/Bildupload Leerzeichen durch + Zeichen ersetzt und Sonderzeichen durch den entsprechenden Hexadezimalwert. Der erste zeigt die Domain, der zweite Wert zeigt an, ob der Cookie von einer ssl Verbindung erzeugt wurde, der dritten Wert zeigt an, ob ein Pfad angegeben wurde. Die Angabe eines Pfades bewirkt, dass ein Cookie nur gelesen werden darf, wenn der Skript, der ihn lesen will, im selben Ordner liegt wie der Skript, der ihn aufgerufen hat. Verändert man den Skript, so dass der Pfad gesetzt wird,

dann sieht der Eintrag in der Datei Cookie.txt so aus.

127.0.0.1 TRUE /docs FALSE 1039732380 Name Andres+Ehmann

Auslesen eines Cookies

Ein Cookie läßt sich mit PHP sehr leicht auslesen. Die Variablen, die in den Cookie geschrieben wurden, lassen sich einfach aufrufen.

<?
print "Hallo $Name<br>
auch wieder da ?";
?>

Wir erhalten, so der Skript, der den Cookie ausgelöst hat ausgelöst wurden.
Hallo Andres Ehmann
auch wieder da ?

Werte eines Cookies

In den überwiegenden praxisrelevanten Fällen, wie z.B. der Realisierung eines Warenkorbes über Cookies, muss die Möglichkeit bestehen, den Wert eines Cookies zu ändern. Dies ist einfach. Es kann nur einen Cookie mit dem gleichen Namen geben. Wird ein Cookie mit dem gleichen Namen nochmal gesetzt, wird der alte Cookie überschrieben. Wer es ausprobieren will, kann unten stehenden Miniskript nehmen und ihn zwei mal auslösen. Anstatt EINS sollte man dann beim zweiten Mal was anderes schreiben z.B. ZWEI. Es zeigt sich dann, dass der Cookie beim zweiten Mall einen anderen Wert hat, als beim ersten Mal. sleep steht für schlafen, der Skript macht ein Nickerchen. Das braucht man, sonst schafft es der Browser nicht.

<?
setcookie("Test","Cookie Nr. EINS",Time()+1200);
sleep(12);
$kekse="<font color=red size=5>$Test </font><br>";
print "$kekse";
?>

Temporäre Cookies

Man beachte, dass auch so was geht.

<?
setcookie("Test","Cookie Nr. EINS");
sleep(12);
$kekse="<font color=red size=5>$Test </font><br>";
print "$kekse";
?>

Hat die Funktion setcookie keine Zeitangabe, wird der Cookie nur gehalten, bis der Browser geschlossen wird. Eine Datei wird in diesem Falle nicht geschrieben. Browser kann man so einstellen, dass sie nur diese unproblematischen Cookies zulassen. Unproblematisch sind sie deswegen, weil dann keine Möglichkeit besteht, irgendwelche Informationen bei einem erneuten Aufruf der Seite zu übergeben. Die Einstellung kann man bei Internetexplorer einstellen mit Extras->Internetoptionen->Datenschutz->Erweitert. Dann in der Schaltfläche Cookies sperren aktivieren (dann sind erstmal alle Cookies gesperrt und gleichzeitig Sitzungscookies immer zulassen aktivieren. Die Änderung wird erst aktiv, wenn der Browser erneut geöffnet wird. Die meisten Probleme, z.B. eine Warenkorbfunktion, lassen sich mit dieser simplen Methode nicht realisieren. Man könnte zwar jedes Produkt einspeisen und als Name die eindeutige Bestellnummer und als Wert die bestellte Menge übergeben und so jedes bestellte Produkt abspeichern, wir wüssten aber nicht was er bestellt hat und folglich wüssten wir auch den Variablennamen nicht und folglich würden wir die bestellten Waren nie mehr aus dem Cookie heraus bekommen. Eine Lösung für dieses Problem besteht darin, alle Waren in einem Array zu speichern und dann diesen Array komplett in einem Cookie abzuspeichern. Wir vernachlässigen jetzt erstmal die Tatsache, dass eine praktisch gangbare Lösung eigentlich nur über einen zweidimensionalen Array möglich wäre, da zu jedem Produkt eine ganze Reihe von Daten abzuspeichern sind (Bestellnummer, Hersteller, Produktname, Menge, Preis, Varianten etc. ). Ein kompletter Array läßt sich folgendermassen in einem Cookie spreichern.

Einen Array in einem Cookie speichern

<?
$alle_zusammen=array("Andres Ehmann","Maria Gonzales",
"Shokufeh Mahmoodzadeh","Clinch die Messerklinge");
$zeichenkette=implode("||",$alle_zusammen);
setcookie("mein_array",$zeichenkette,Time()+3600);
print "Der Array wurde eingespeist";
?>

Lösen wir den Skript aus und schauen was passiert. Was wir erhalten als Cookie sieht so aus.

mein_array
Andres+Ehmann%7C%7CMaria+Gonzales%7C%7CShokufeh+Mahmoodzadeh%7C%7CClinch+die+Messerklinge
127.0.0.1/
1024
2067424512
29532853
430262880
29532845
*

Das heisst, die zwei Pipes ( | | ) die als Delimiter fungieren, siehe Funktionen zum Bearbeiten von Zeichenketten und Formulareingaben auswerten/Bildupload werden, ähnlich wie beim Query String in Hexadezimalschreibweise geschrieben. Darum brauchen wir uns nicht weiter zu kümmern, da PHP diesen Vorgang wieder rückgängig macht, wenn mit der Variablen gearbeitet wird.
Es ist somit ein leichtes, den ganzen Array wieder auszulesen.

<?
$alle_zusammen=array();
$alle_zusammen=explode("||","$mein_array");
foreach ($alle_zusammen as $einzelner_wert)
{
print "$einzelner_wert <br>";
}
?>

Auf dem Bildschirm erscheint dann sowas.
Andres Ehmann
Maria Gonzales
Shokufeh Mahmoodzadeh
Clinch die Messerklinge

Dieser Array lässt sich dann, soweit man das braucht, manipulieren (sortieren, löschen von Elementen, ändern von Elementen, hinzufügen von Elementen etc. ) und wieder zurückschreiben. Über diesen Weg könnte man dann auch komplexere Anwendungen realisieren.

Sessions

Theoretisch könnte man eine eindeutige Identifizierung des Users auch über Cookies realisieren. Php stellt aber noch einen Mechanismus bereit, die Sessions, die auch dann funktionnieren, wenn der User Cookies deaktiviert hat (hat er dies nicht, arbeiten auch die Sessions mit Cookies). Sessions werden im allgemeinen kurz und bündig abgehandelt, so nach dem Motto, ist nicht schwierig. Man muss diese Auffassung nicht teilen. Eigentlich ist es ein bisschen tricki. Der kleine Skript unten veranschaulicht die Zusammenhänge.

<?
session_start();
$idname=session_name();
$idwert=session_id();

if(!$modul)
{
print "Wert des Cookies:".$idwert."<br>";
print "Name des Cookies:".$idname."<br>";
print "Wir gehen jetzt weiter zur url <a href=keks.php?modul=ja>weiter</a>";
}
else
{
print "Wert des Cookies:".$idwert."<br>";
print "Name des Cookies:".$idname."<br>";
print "hallo";
}
?>

Lösen wir diesen Skript aus, sehen wir zuerst das.
Wert des Cookies:697b0abd95d14c9c907d1f6b2cacb122
Name des Cookies:PHPSESSID
Wir gehen jetzt weiter zur url weiter

Drücken wir dann auf weiter, sehen wir das
Wert des Cookies:697b0abd95d14c9c907d1f6b2cacb122
Name des Cookies:PHPSESSID
hallo

Der selbe Skript wurde also zweimal aufgerufen. Einmal der erste Teil, der von der if Bedingung abhängt und einmal der Teil, der von der else Bedingung abhängt. (Bemerkung zur if Bedingung: Jeder Wert ungleich 0 oder undef ist true. Diesen Wert verneinen wir mit dem Ausrufezeichen, so dass die if Bedingung den Wert true hat, wenn die Variable $modul nicht existiert. Hinsichtlich Übergabe der Variablen in der else-Bedingung (?modul=ja) siehe Formulareingaben auswerten/Bildupload). Wie wir sehen, ist die Session ID, das heisst die ziemlich lange Zahl die das steht, beides mal die gleiche, damit wissen wir, dass es sich um die selbe Sitzung handelt, wir können also einen Surfer, der von Seite zu Seite hopst, als geschlossenen Vorgang erfassen. Wie funktionniert es im Detail? Die Funktion session_start startet eine Session, das heisst zu deutsch, sie generiert eine Sessionnummer, in diesem Fall 697b0abd95d14c9c907d1f6b2cacb122 und einen Sessionname, in diesem Fall PHPSESSID der immer gleich ist und den man in der php.ini Datei verändern kann, wenn er einem nicht gefällt. Die Funktion session_start erkennt, ob eine Session bereits gestartet wurde oder nicht. Ist noch keine Session gestartet, startet sie eine Session, ist schon eine gestartet, werden die Werte die bereits vorliegen wieder reinitialisiert. Ruft man also den Skript oben zum ersten mal auf, wird eine Session gestartet, beim zweiten Aufruf werden lediglich die bereits vorliegenden Werte reinitialisiert. Auf diese Weise ist gewährleistet, dass die Variablen $idwert und $idname (die über die Funktionen session_id bzw. session_name abgerufen werden) immer gleich sind. Man kann jetzt noch eine Fallunterscheidung machen. Sind die Cookies deaktiviert, wird die Variable $idwert an jeden Hyperlink und jeden Aufruf eines Programms aus einem Formular angehängt. Das selbe Beispiel von oben, zeigen wir jetzt nochmal, bzw. den HTML Quelltext, aus einer Situation heraus, in der die Cookies deaktiviert worden sind. Das sieht dann so aus.

Wert des Cookies:3a4283ded3907dbd27e1be262926335e<br>
Name des Cookies:PHPSESSID<br>
Wir gehen jetzt weiter zur url
<a href="keks.php?modul=ja&PHPSESSID=3a4283ded3907dbd27e1be262926335e">weiter</a>

Das Beispiel kann nur funktionnieren, wenn die Cookies im Browser deaktiviert sind,
(im Explorer: Extras->Internetoptionen->Datenschutz->Erweitert->Cookies Sperren,
Netscape: Bearbeiten->Einstellungen->Privatsphäre und Sicherheit->Cookies->Cookies deaktivieren)
weil PHP ja sonst automatisch den Cookie clientseitig einrichtet und Sessions in der php.ini Datei aktiviert sind. Wir sehen also, dass in dieser Situation der Name der Session (PHPSESSID) und der Wert der Session an die Url angehängt wurden. So ist es PHP möglich, den in dieser Situation serverseitig abgespeicherten Cookie (Clientseitig ist ja nicht möglich, da Cookies deaktiviert wurden) , der zu der entsprechenden Sitzung gehört, zu finden.

Sessions in der php.ini aktvieren

Allerdings funktionniert das nur, wenn die php.ini diese Zeilen enthält.

; use transient sid support if enabled by compiling with --enable-trans-sid.

session.use_trans_sid = 1

Dieses serverseitige Abspeichern des Cookies findet in dem Verzeichnis statt, dass in der php.ini angegeben wurde. Der Default ist c:/tmp. Schauen wir nach, sehen wir in diesem Ordner eine Datei mit dem Namen
sess_3a4283ded3907dbd27e1be262926335e.

Wir zeigen es anhand des Internet Explorers, für Netscape ist es ähnlich. Öffnen wir diese Datei mit Wordpad, sehen wir, dass nichts enthalten ist. Die Session nützt uns also noch nicht viel, wiel wir keine Variablen abspeichern können. Wenn wir also tatsächlich Variablen abspeichern wollen, müssen wir der Session noch Werte zuweisen. Wollen wir einer Session Werte zuweisen, brauchen wir die Funktion session_start nicht mehr, weil diese Funktion in der Funktion session_register, mit der wir unserem Cookie Werte zuweisen, bereits enthalten ist. Wir zeigen das Beispiel von oben nochmal mit Wertzuweisung.

<?
session_register("Nachname","Vorname","Telefon");
$idname=session_name();
$idwert=session_id();
if(!$modul)
{
$Nachname="Ehmann";
$Vorname="Andres";
$Telefon="030-47301386";
print "Wert des Cookies:".$idwert."<br>";
print "Name des Cookies:".$idname."<br>";
print "Wir gehen jetzt weiter zur url <a href=keks.php?modul=ja>weiter</a>";
}
else
{
print "Wert des Cookies:".$idwert."<br>";
print "Name des Cookies:".$idname."<br>";
print "hallo <br>";
print "Die Telefonnummer von $Vorname $Nachname ist $Telefon";
}

?>

Wir haben wieder den gleichen Skript mit einer leichten Veränderung in der ersten Zeile. Anstatt session_start haben wir session_register. Der Funktion session_register übergeben wir soviele Werte, wie wir Variablen initialisieren wollen. Wird der Skript zum ersten Mal aufgerufen, wird die if Bedingung abgearbeitet. Wir weisen hier den drei Variablen $Nachname, $Vorname, $Telefon Werte zu. Die Werte dieser Variablen stehen dann beim erneuten Aufruf des Skriptes mit weiter zur Verfügung. Das ganze ist wohl etwas gewöhnungsbedürftig. Man muss halt akzeptieren, dass die in einer Session definierten Variablen im ganzen Skript als globale Variablen zur Verfügung stehen.

vorhergehendes Kapitel