|

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 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.
<?
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 |
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 ?
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";
?>
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.
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.
|
 |