mitmario.dev

Das Vorhaben

PHP Sandbox 4 Min Lesezeit 2 BeispieleLektion 1 von 7

Die letzten siebzehn Abschnitte haben dir Bausteine gegeben. Einen Front Controller, eine Vorlage, eine Sitzung, eine Anmeldung, eine Datenbank, ein Token, eine Handvoll Tests. Jeder davon hat für sich funktioniert, und jeder stand in einer Lektion, die genau dafür gebaut war.

Ab jetzt steht hinter jeder Lektion dieselbe Anwendung. Die ist erst fertig, wenn alle Teile zusammen laufen, und jede der nächsten fünf Aufgaben ist ein Stück davon.

Was am Ende dasteht

Eine Verwaltung für Lesezeichen. Klein, aber vollständig: Man legt sich ein Konto an, meldet sich an, trägt Adressen ein, ändert und löscht sie wieder und durchsucht sie. Wer angemeldet ist, sieht seine eigenen Lesezeichen und sonst keine. Wer nicht angemeldet ist, sieht gar nichts.

Das klingt nach wenig. Es ist trotzdem genau das, was die meisten kleinen Anwendungen im Netz tun: Daten annehmen, prüfen, jemandem zuordnen, speichern, wieder ausgeben. Der Rest ist Ausstattung.

Und du wirst sie benutzen. Ab der übernächsten Lektion steht im Reiter Browser eine Seite, auf der du dich wirklich anmeldest, wirklich etwas einträgst und wirklich etwas löschst. Die Prüfliste sagt dir, ob dein Code stimmt. Die Seite im Browser sagt dir, ob die Anwendung sich richtig anfühlt. Das sind zwei verschiedene Fragen, und beide gehören dazu.

Die Ablage

Die Ordner der Anwendung
<?php

declare(strict_types=1);

// Die Ablage des Projekts, mit einem Satz zu jedem Eintrag. Genau die
// Struktur aus Lektion 16.7, nur mit anderen Namen darin.

$ablage = [
    "konfiguration.php" => "Was sich zwischen deinem Rechner und dem Server unterscheidet.",
    "oeffentlich/" => "Das einzige Verzeichnis, das der Webserver kennt.",
    "oeffentlich/index.php" => "Der Front Controller. Jede Anfrage kommt hier an.",
    "src/" => "Der Code. Von aussen nicht erreichbar.",
    "src/funktionen.php" => "Die kleinen Helfer: maskieren, rendern, Routen vergleichen.",
    "src/LesezeichenSpeicher.php" => "Alles, was mit der Datenbank spricht. Und sonst nichts.",
    "src/routen.php" => "Welche Adresse zu welcher Funktion gehoert.",
    "src/seiten.php" => "Je Adresse eine Funktion. Sie geben Text zurueck, sie geben nichts aus.",
    "ansichten/" => "Die Vorlagen. Hier steht HTML und keine Abfrage.",
    "privat/" => "Die Datenbankdatei. Ebenfalls ausserhalb der Dokumentwurzel.",
];

foreach ($ablage as $pfad => $zweck) {
    $tiefe = substr_count(rtrim($pfad, "/"), "/");
    $name = basename($pfad) . (str_ends_with($pfad, "/") ? "/" : "");

    echo str_repeat("    ", $tiefe), str_pad($name, 30 - $tiefe * 4), $zweck, "\n";
}

echo "\nDateien: ", count(array_filter(array_keys($ablage), fn (string $p) => !str_ends_with($p, "/"))), "\n";

Das ist die Struktur aus Lektion 16.7, nur mit anderen Namen darin. Zehn Einträge, und jeder hat einen Grund:

  • oeffentlich/ ist das einzige Verzeichnis, das der Webserver kennt. Genau eine PHP-Datei liegt darin. Alles andere ist von außen nicht erreichbar, und zwar nicht, weil es niemand ahnt, sondern weil der Server es nicht ausliefern kann.
  • src/ ist der Code. Eine Datei für die Datenbank, eine für die Seiten, eine für die Routen, eine für die Helfer. Wer eine Zeile sucht, weiß nach dieser Aufteilung, wo er nachsieht.
  • ansichten/ ist das HTML. Dort steht keine Abfrage, dorthin kommen nur fertige Werte.
  • privat/ ist die Datenbankdatei. Auch die liegt außerhalb der Dokumentwurzel, und Lektion 15.6 hat gezeigt, warum: Läge sie daneben, könnte man sie herunterladen.

Der Weg einer Anfrage

Eine Anfrage von vorne bis hinten
<?php

// Ein Front Controller in klein, und er schreibt mit, was er tut. Klick
// im Reiter Browser auf die Links: Die fuenf Stationen bleiben dieselben,
// nur die Werte darin aendern sich.

require __DIR__ . "/../src/stationen.php";

$pfad = parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH);

notiere("1. Anfrage angekommen", $_SERVER["REQUEST_METHOD"] . " " . $pfad);

$routen = [
    "/" => "seiteStart",
    "/ueber" => "seiteUeber",
];

notiere("2. Routentabelle gelesen", count($routen) . " Eintraege");

if (isset($routen[$pfad])) {
    notiere("3. Route gefunden", $routen[$pfad] . "()");
    $inhalt = $routen[$pfad]();
} else {
    http_response_code(404);
    notiere("3. Keine Route gefunden", "Statuscode 404");
    $inhalt = "<p>Diese Adresse kennt der Front Controller nicht.</p>";
}

notiere("4. Inhalt steht", strlen($inhalt) . " Zeichen");
notiere("5. Vorlage drumherum", "und genau einmal ausgeben");

echo rendere($inhalt);

Das zweite Beispiel ist die Anwendung im Kleinen. Es hat zwei Seiten und keine Datenbank, aber es läuft dieselben fünf Stationen durch wie das fertige Projekt, und es schreibt jede davon mit. Klick im Reiter Browser durch die Links und sieh dir die Tabelle unten auf der Seite an.

Fünf Stationen, immer dieselben. Die Anfrage kommt an, der Front Controller liest die Routentabelle, er sucht die passende Zeile, die gefundene Funktion baut den Inhalt, und ganz am Ende wird genau einmal ausgegeben. Ruf auch die dritte Adresse auf, die es nicht gibt: Dann fehlt Station drei, und an ihre Stelle tritt ein Statuscode, den dein Code gesetzt hat.

Diese Reihenfolge ändert sich in den nächsten fünf Lektionen kein einziges Mal. Was sich ändert, ist die Routentabelle und die Zahl der Funktionen dahinter. Wenn du also irgendwann nicht weißt, wohin dein Code gehört, dann geh diese fünf Stationen durch und frag dich, an welcher er passiert.

Was bewusst fehlt

Die Anwendung kann eine Menge nicht, und das ist kein Versehen:

  • Kein Passwort vergessen. Dafür bräuchte es E-Mail, und E-Mail lässt sich hier nicht ehrlich zeigen.
  • Keine Rechte über die eigenen Daten hinaus. Es gibt keine Rolle, keinen Verwalter, keine geteilten Listen. Es gibt nur: gehört dir oder gehört dir nicht.
  • Keine Paginierung, keine Sortierung nach Klick, keine Ordner. Alles davon ist eine Übung wert, aber keine bringt etwas Neues bei.
  • Kein Deployment. Wie diese Anwendung auf einen echten Server kommt, ist ein eigener Kurs, samt Git, HTTPS und Datensicherung.

Wie die nächsten fünf Lektionen laufen

Jede ist ein Arbeitsauftrag an derselben Anwendung, und jede steht für sich. Du bekommst die Anwendung in dem Zustand, den der Auftrag braucht, und baust ein Stück daran. Nichts davon musst du aus einer früheren Lektion herüberretten, und du kannst die fünf auch in einer anderen Reihenfolge machen oder eine auslassen. Die Reihenfolge unten ist die, in der die Anwendung wächst, und darum die, die sich am besten liest.

In 18.2 entsteht die Datenbasis: zwei Tabellen und die Klasse, die sie bedient. Das ist die einzige Lektion, die noch auf der Kommandozeile spielt. In 18.3 kommt die Anmeldung dazu, und ab da läuft die Anwendung im Reiter Browser. 18.4 bringt das Anlegen und Anzeigen, 18.5 das Bearbeiten und Löschen samt der Frage, wem ein Eintrag eigentlich gehört, und 18.6 die Suche.

Im Editor liegen dabei nur die Dateien, um die es geht. Die Anwendung hat zehn, gearbeitet wird in einer, und eine zweite brauchst du zum Nachsehen. Der Rest steht unter Dateien: Konfiguration, Helfer, Routentabelle, Ansichten, Front Controller. Die laufen alle mit, du kannst jede davon aufmachen und lesen, aber sie stehen dir nicht im Weg, bevor du die Aufgabe gefunden hast. Was du dort siehst, ist die Lösung der Lektionen davor, in der Form, die dieser Kurs gewählt hat. Hast du eine Lücke anders gefüllt, ist das kein Fehler, nur eine andere Form.

Der Aufgabentext sagt dir jedes Mal am Ende, was du im Browser neu ausprobieren kannst. Nimm dir die Minute dafür. Extra starten musst du dafür nichts: Nach einem Klick auf Prüfen läuft die Anwendung als Sitzung weiter und zieht bei jeder Änderung nach, genau wie nach Sandbox starten. Nach fünf Minuten, in denen du nichts tust, endet die Sitzung, angesagt eine Minute vorher, und Sandbox starten holt sie zurück.

Zum Mitnehmen

Ein Abschnitt ohne neuen Stoff, und trotzdem der schwerste. Alles, was du brauchst, hast du schon einmal gemacht. Neu ist nur, dass es diesmal zusammen funktionieren muss.

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 2 Beispielen zum Ausprobieren

    Steht hier, ohne Konto lesbar.