mitmario.dev

Warum sich nichts merkt

PHP Sandbox 4 Min Lesezeit 3 BeispieleLektion 1 von 6

Bis hierhin ging jede Lektion so: Eine Anfrage kommt an, dein Programm läuft, eine Antwort geht hinaus. Was dabei nie zur Sprache kam: Was passiert eigentlich mit dem, was dein Programm sich dabei gemerkt hat?

Die Antwort ist unbequem. Es ist weg.

Jede Anfrage fängt bei null an

Der Zähler, der bei jedem Aufruf wieder bei eins steht
<?php

// Diese Seite zaehlt ihre eigenen Aufrufe. Jedenfalls sieht es so aus.
//
// Lad die Seite im Browser ein paar Mal neu und sieh dir die Zahl an.

$aufrufe = 0;
$aufrufe++;

?>
<!doctype html>
<html lang="de">
<head>
    <meta charset="utf-8">
    <title>Zaehler</title>
</head>
<body>
    <h1>Aufrufe: <?= $aufrufe ?></h1>
    <p>Lad die Seite neu. Die Zahl bleibt, wo sie ist.</p>
    <p><a href="/">Noch einmal aufrufen</a></p>
</body>
</html>

Das erste Beispiel zählt seine eigenen Aufrufe. Es setzt einen Zähler auf null, zählt ihn um eins hoch und gibt ihn aus. Lad die Seite im Browser neu, so oft du willst: Da steht eine Eins.

Der Grund ist nicht der Zähler, sondern das, was zwischen zwei Anfragen passiert, nämlich nichts. Dein Programm läuft von oben nach unten durch, schickt seine Antwort und ist danach zu Ende. Alle Variablen sind weg, so wie bei einem Skript in Abschnitt 1 bis 9. Die nächste Anfrage startet das Programm noch einmal, von der ersten Zeile an, und die erste Zeile setzt den Zähler auf null.

Das ist kein Versehen im Entwurf von HTTP, sondern eine Entscheidung. Man nennt es zustandslos: Der Server behält zwischen zwei Anfragen von sich aus nichts.

Warum das eine gute Eigenschaft ist

Ein Server, der sich nichts merkt, kann tausend Besucher gleichzeitig bedienen, ohne sie zu verwechseln. Jede Anfrage steht für sich, jede bekommt einen frischen Lauf, und keine kann eine andere durcheinanderbringen. Fällt eine Maschine aus, übernimmt die nächste, denn es gibt nichts, was nur die eine wusste.

Das ist der Grund, warum das Web so groß werden konnte. Und es ist derselbe Grund, aus dem eine Anmeldung so viel Arbeit macht.

Was es kostet

Was bei einer Anfrage wirklich ankommt
<?php

// Alles, was der Server ueber dich weiss, steht in dieser Anfrage.
// Mehr hat er nicht: keine Erinnerung, keine Liste von Besuchern.
//
// Ruf im Browser ein paar verschiedene Adressen auf und sieh zu, was
// sich aendert und was gleich bleibt.

$cookies = $_SERVER["HTTP_COOKIE"] ?? "(gar keine)";

?>
<!doctype html>
<html lang="de">
<head>
    <meta charset="utf-8">
    <title>Deine Anfrage</title>
</head>
<body>
    <h1>Das ist alles, was ankommt</h1>

    <p>Methode: <code><?= htmlspecialchars($_SERVER["REQUEST_METHOD"]) ?></code></p>
    <p>Adresse: <code><?= htmlspecialchars($_SERVER["REQUEST_URI"]) ?></code></p>
    <p>Mitgeschickte Cookies: <code><?= htmlspecialchars($cookies) ?></code></p>

    <p>
        <a href="/">Startseite</a> ·
        <a href="/preise">Preise</a> ·
        <a href="/?suche=Kaffee">Suche</a>
    </p>
</body>
</html>

Der Server erkennt niemanden wieder. Alles, was er über dich weiß, steht in dieser einen Anfrage: die Methode, die Adresse, ein paar Kopfzeilen. Mehr nicht. Das dritte Beispiel zeigt genau das. Klick dich im Browser durch die drei Links und sieh zu, was sich ändert. Die Seite liest dabei nur vor, was ohnehin angekommen ist: Im Reiter Netzwerk steht zu jedem Klick dieselbe Anfrage, und unter den Anfrage-Kopfzeilen dieselbe cookie-Zeile, so wie der Browser sie hingeschickt hat.

Steht bei den Cookies „gar keine”, dann hat der Server keine Möglichkeit zu wissen, ob du gerade zum ersten oder zum fünfzigsten Mal da bist. Steht dort schon etwas, stammt es aus einem der Beispiele davor, und damit sind wir bei der Antwort, um die es gleich geht. Für eine Preisliste ist das egal. Für einen Warenkorb ist es tödlich, und für eine Anmeldung erst recht: Wer sich anmeldet und auf den nächsten Link klickt, wäre sofort wieder ein Fremder.

Die zwei Antworten darauf

Es gibt genau zwei Orte, an denen etwas liegen bleiben kann, und beide bekommen in diesem Abschnitt eine eigene Lektion.

Beim Besucher. Der Server bittet den Browser, sich einen kleinen Zettel zu merken, und der Browser schickt ihn bei jeder weiteren Anfrage von selbst wieder mit. Das ist ein Cookie, und es ist der Stoff von Lektion 12.2. Der Zettel liegt damit auf einem Rechner, der dir nicht gehört, und das hat Folgen, über die wir dort ausführlich reden.

Beim Server. Der Server legt die Daten bei sich ab und gibt dem Besucher nur eine Nummer mit. Beim nächsten Mal schickt der Browser die Nummer, der Server sucht seine Daten heraus, und alles ist wieder da. Das ist eine Sitzung, Lektion 12.3.

Die Nummer selbst liegt übrigens auch in einem Cookie. Eine Sitzung ist damit kein Gegenentwurf zum Cookie, sondern eine Anwendung davon: das kleinstmögliche Cookie, in dem nichts steht außer einer Kennung.

Wie sich das anfühlt

Derselbe Zähler in einer Sitzung
<?php

// Dieselbe Seite, zwei Zeilen anders. Der Wert liegt jetzt nicht mehr
// in einer Variablen, sondern in einer Sitzung, und die lebt beim
// Server weiter, waehrend dein Programm laengst zu Ende ist.
//
// Lad die Seite im Browser ein paar Mal neu.

session_start();

$_SESSION["aufrufe"] = ($_SESSION["aufrufe"] ?? 0) + 1;

?>
<!doctype html>
<html lang="de">
<head>
    <meta charset="utf-8">
    <title>Zaehler</title>
</head>
<body>
    <h1>Aufrufe: <?= $_SESSION["aufrufe"] ?></h1>
    <p>Lad die Seite neu. Jetzt steigt die Zahl.</p>
    <p><a href="/">Noch einmal aufrufen</a></p>
</body>
</html>

Das zweite Beispiel ist dieselbe Seite wie das erste. Zwei Zeilen sind anders: session_start() am Anfang, und der Zähler liegt in $_SESSION statt in einer gewöhnlichen Variablen.

Lad es im Browser neu. Die Zahl steigt.

Nichts an der Zustandslosigkeit hat sich geändert. Dein Programm ist nach jeder Antwort immer noch zu Ende, alle Variablen sind immer noch weg, und der nächste Aufruf fängt immer noch oben an. Was sich geändert hat, ist der Ort: Der Wert liegt jetzt woanders und wird beim nächsten Lauf wieder hervorgeholt.

Zwischen den beiden Beispielen liegt dieser ganze Abschnitt. Wie das im Einzelnen funktioniert, was dabei zum Browser geht und was beim Server bleibt, und warum man an genau dieser Stelle vorsichtig sein muss, kommt in den nächsten vier Lektionen.

Eine Sache noch, damit du dich nicht wunderst: Im Terminal steht in dieser Lektion nur der Befehl, der den Server startet, und darunter nichts. Ein Server schreibt seine Seiten nicht auf die Ausgabe, er verschickt sie. Alles, worum es hier geht, steht im Browser, und was dabei hin und her geht, im Reiter Netzwerk.

Zum Mitnehmen

Diese Lektion hat keine Aufgabe, sondern drei Beispiele und einen Handgriff: die Seite im Browser noch einmal aufrufen. Der Unterschied zwischen dem ersten und dem zweiten Beispiel ist der ganze Abschnitt, und er zeigt sich erst beim zweiten Aufruf.

Jetzt du

Basis Konto, kostenlos

Im Editor änderst du die Beispiele dieser Lektion und lässt sie gleich laufen. So merkst du am schnellsten, ob es sitzt.

Dafür brauchst du das Basis Konto. Es kostet nichts, und ein Passwort gibt es auch nicht.

In diesem Kurs läuft dein Code auf einem Server. Dafür hat das Basis Konto 1 Stunde im Monat, mehr Zeit gibt es mit dem Premium Konto.

Was in dieser Lektion steckt

  • Artikel mit 3 Beispielen zum Ausprobieren

    Steht hier, ohne Konto lesbar.