mitmario.dev

Anfrage und Antwort

PHP Sandbox 4 Min Lesezeit 3 BeispieleLektion 1 von 7

Bis hierhin hast du Programme geschrieben, die du selbst gestartet hast. Ab der nächsten Lektion startet sie jemand anderes, nämlich ein Browser, der eine Adresse aufruft. Zwischen ihm und deinem Code liegt eine Absprache, die seit den Neunzigern gilt und die man an einem Nachmittag versteht.

Sie heißt HTTP und besteht aus zwei Nachrichten. Der Browser schickt eine Anfrage, der Server schickt eine Antwort. Beide sind schlichter Text, und beide haben denselben Aufbau: eine erste Zeile, darunter Kopfzeilen, dann eine Leerzeile und dahinter der eigentliche Inhalt.

Die Anfrage

Was der Browser hinschickt
<?php

// Das hier ist keine echte Anfrage, sondern eine hingeschriebene.
// Genau so sieht sie aus, wenn sie ueber die Leitung geht.

$anfrage = <<<TEXT
GET /preise.php?sortierung=preis HTTP/1.1
Host: hofladen.example
Accept: text/html
Accept-Language: de-DE
TEXT;

echo $anfrage, "\n";

$zeilen = explode("\n", $anfrage);
$ersteZeile = explode(" ", $zeilen[0]);
$ziel = explode("?", $ersteZeile[1]);

echo "\nZerlegt:\n";
echo "  Methode:    ", $ersteZeile[0], "\n";
echo "  Pfad:       ", $ziel[0], "\n";
echo "  Anhang:     ", $ziel[1], "\n";
echo "  Kopfzeilen: ", count($zeilen) - 1, "\n";

Die erste Zeile ist die wichtige. Sie besteht aus drei Teilen, und die stehen im Beispiel unten noch einmal einzeln da.

Die Methode sagt, was passieren soll. GET heißt „gib mir das”, und das ist alles, was ein Browser tut, wenn du eine Adresse eintippst oder einen Link anklickst. Ab Abschnitt 11 kommt POST dazu, mit dem man etwas hinschickt statt etwas zu holen. Es gibt noch ein paar weitere, aber diese zwei tragen fast das ganze Netz.

Der Pfad ist alles hinter dem Servernamen. Er sagt, welche Seite gemeint ist. Steht ein Fragezeichen darin, gehört alles dahinter nicht mehr zum Pfad, sondern ist ein Anhang aus Schlüsseln und Werten. Der ist der Stoff von Lektion 10.3.

Die Version am Ende ist Formsache und für dich nie ein Thema.

Darunter stehen die Kopfzeilen, immer als Name: Wert. Der Browser schickt einige mit, ohne dich zu fragen: welchen Server er meint, was für ein Programm er ist, welche Sprache er lieber hätte. Für dich sind sie meistens nur Zusatzinformation. Eine davon wird später wichtig, nämlich die mit den Cookies in Abschnitt 12.

Die Antwort

Was zurückkommt
<?php

$rumpf = "<h1>Preise</h1>\n<p>Kaffee: 8,50 Euro</p>\n";

echo "So kommt die Antwort zurueck:\n\n";

echo "HTTP/1.1 200 OK\n";
echo "Content-Type: text/html; charset=UTF-8\n";
echo "Content-Length: ", strlen($rumpf), "\n";
echo "\n";
echo $rumpf;

echo "\nDie Leerzeile ist die Grenze: darueber Kopfzeilen, darunter Inhalt.\n";

Die Antwort ist genauso gebaut, nur heißt die erste Zeile hier Statuszeile, und in ihr steht eine dreistellige Zahl. Die ist die kürzeste Zusammenfassung, die es gibt: Ging es gut, ging es schief, und wenn ja, an wem lag es.

Vier Zahlen kommen in diesem Kurs vor, und mehr braucht man am Anfang nicht:

  • 200 OK heißt, dass alles geklappt hat. Der Inhalt ist dabei.
  • 302 Found heißt „such woanders weiter”. In der Antwort steht dann eine Kopfzeile Location mit der neuen Adresse, und der Browser geht von selbst dorthin. Das ist der Stoff von Lektion 11.3, und es fühlt sich beim ersten Mal wie Zauberei an.
  • 404 Not Found heißt, dass es unter diesem Pfad nichts gibt. Der Fehler liegt beim Fragenden.
  • 500 Internal Server Error heißt, dass dein Code abgestürzt ist. Der Fehler liegt bei dir.

Unter der Statuszeile stehen wieder Kopfzeilen. Die wichtigste ist Content-Type, denn sie sagt dem Browser, was er da überhaupt bekommen hat. Steht dort text/html, baut er eine Seite daraus. Steht dort text/plain, zeigt er denselben Text mit allen spitzen Klammern an. Es ist dieselbe Zeichenkette, nur einmal so und einmal so gelesen.

Und dann die Leerzeile. Sie ist keine Verzierung, sondern die Grenze. Alles darüber sind Angaben über die Nachricht, alles darunter ist die Nachricht. Genau diese Grenze ist der Grund für eine Regel, die dich in Lektion 10.4 einholt: Kopfzeilen kann man nur setzen, solange noch nichts ausgegeben wurde.

Dieselbe Adresse, verschiedene Antworten

Dieselbe Adresse, drei Antworten
<?php

function antwort(string $statuszeile, string $typ, string $rumpf): string
{
    return $statuszeile . "\n"
        . "Content-Type: " . $typ . "\n"
        . "Content-Length: " . strlen($rumpf) . "\n"
        . "\n"
        . $rumpf . "\n";
}

echo "Dreimal /preise, je nachdem wie es gelaufen ist:\n\n";

echo antwort("HTTP/1.1 200 OK", "text/html; charset=UTF-8", "<h1>Preise</h1>");
echo "----------\n";
echo antwort("HTTP/1.1 404 Not Found", "text/html; charset=UTF-8", "<h1>Nicht gefunden</h1>");
echo "----------\n";
echo antwort("HTTP/1.1 200 OK", "application/json", '{"kaffee":850}');

Hier stehen drei Antworten untereinander, und alle drei könnten auf dieselbe Anfrage kommen. Einmal die Seite, einmal die Meldung, dass es sie nicht gibt, einmal dieselben Daten als JSON für ein anderes Programm statt für einen Menschen.

Das ist der Punkt, an dem sich das Bild aus dem HTML-Kurs endgültig verschiebt. Eine Adresse ist kein Ort auf einer Festplatte. Sie ist eine Frage, und was zurückkommt, entscheidet dein Programm.

Der Browser bleibt diesmal leer, und das ist richtig

Was die Beispiele hier ausgeben, ist eine Antwort als Text. Die drei laufen noch wie alles bis Abschnitt 9, also mit php index.php, und der Text steht im Terminal, mit allen Zeilen und der Leerzeile in der Mitte. Genau so sollst du ihn lesen können.

Eine Seite entsteht daraus nicht, denn niemand hat diese Antwort verschickt. Ab der nächsten Lektion läuft ein echter Server, und dann siehst du beide Nachrichten an ihrem Platz: im Reiter Browser die Seite, die aus der Antwort wird, und im Reiter Netzwerk die Anfrage und die Antwort selbst, mit Methode, Pfad, Statuszeile und Kopfzeilen. Was du hier von Hand hingeschrieben hast, steht dort dann bei jedem Klick, ohne dass du etwas dafür tust.

Und die Sache, die alles verändert

Zum Schluss der Satz, an dem du dich in den nächsten acht Abschnitten immer wieder festhalten wirst.

Jede Anfrage ist ein neuer Lauf deines Programms. Der Server startet dein Skript, es läuft von oben nach unten, es schreibt eine Antwort, und dann ist es zu Ende. Alle Variablen sind weg. Beim nächsten Klick fängt alles von vorn an, und dein Programm weiß nichts davon, dass derselbe Besucher gerade eben schon einmal da war.

Auf deinem eigenen Rechner ist das anders: Dort läuft ein Programm, solange du es nicht beendest. Hier lebt es Millisekunden. Wer sich das nicht klarmacht, schreibt irgendwann eine Variable, in der sich der Warenkorb merken soll, und wundert sich, warum er beim nächsten Klick leer ist.

Wie man trotzdem etwas behält, steht in Abschnitt 12. Bis dahin gilt: nichts bleibt.

Zum Mitnehmen

Neun Abschnitte lang war deine Ausgabe ein Text auf der Kommandozeile. Ab jetzt ist sie eine Antwort an jemanden, der gefragt hat. Diese Lektion zeigt, wie diese Frage und diese Antwort wirklich aussehen, bevor du in der nächsten deine erste Seite auslieferst.

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.