Abschnitt 10 · Lektion 6
Vorlagen einbinden
Deine Seiten sehen alle gleich aus, jedenfalls oben und unten. Dieselbe Dokumenttyp-Angabe, derselbe Kopfbereich, dieselbe Navigationsleiste, derselbe Fußbereich. Nur das in der Mitte ist jedes Mal anders.
Wie es aussieht, wenn man es nicht tut
<?php
// Achtung: In dieser Datei fehlt der dritte Menuepunkt. Jemand hat
// Kontakt spaeter dazugebaut und diese Seite uebersehen.
echo "<!doctype html>\n";
echo "<html lang=\"de\">\n";
echo "<head><meta charset=\"utf-8\"><title>Impressum</title></head>\n";
echo "<body>\n";
echo '<nav><a href="/">Start</a> | <a href="/impressum.php">Impressum</a></nav>' . "\n";
echo "<h1>Impressum</h1>\n";
echo "<p>Hofladen GmbH, Dorfstrasse 1.</p>\n";
echo "<footer><p>Hofladen, 2026</p></footer>\n";
echo "</body></html>\n"; <?php
echo "<!doctype html>\n";
echo "<html lang=\"de\">\n";
echo "<head><meta charset=\"utf-8\"><title>Kontakt</title></head>\n";
echo "<body>\n";
echo '<nav><a href="/">Start</a> | <a href="/impressum.php">Impressum</a> | <a href="/kontakt.php">Kontakt</a></nav>' . "\n";
echo "<h1>Kontakt</h1>\n";
echo "<p>Telefon 0123 456789.</p>\n";
echo "<footer><p>Hofladen, 2026</p></footer>\n";
echo "</body></html>\n"; <?php
echo "<!doctype html>\n";
echo "<html lang=\"de\">\n";
echo "<head><meta charset=\"utf-8\"><title>Startseite</title></head>\n";
echo "<body>\n";
echo '<nav><a href="/">Start</a> | <a href="/impressum.php">Impressum</a> | <a href="/kontakt.php">Kontakt</a></nav>' . "\n";
echo "<h1>Startseite</h1>\n";
echo "<p>Frisches aus dem Hofladen.</p>\n";
echo "<footer><p>Hofladen, 2026</p></footer>\n";
echo "</body></html>\n"; Drei Dateien, drei Seiten, und die Hülle steht dreimal da. Klick dich im Browser durch alle drei und achte auf die Navigationsleiste.
Auf dem Impressum fehlt der Menüpunkt Kontakt. Jemand hat die Kontaktseite später dazugebaut und zwei von drei Dateien angepasst. Das ist kein erfundenes Beispiel, das ist der Normalfall: Sobald dasselbe an mehreren Stellen steht, geht früher oder später eine davon verloren. Bei drei Dateien merkt man es beim Durchklicken, bei fünfzehn merkt es ein Besucher.
include holt eine Datei herein
<!doctype html>
<html lang="de">
<head><meta charset="utf-8"><title><?= $titel ?></title></head>
<body>
<nav><a href="/">Start</a> | <a href="/impressum.php">Impressum</a> | <a href="/kontakt.php">Kontakt</a></nav> <footer><p>Hofladen, <?= date("Y") ?></p></footer>
</body>
</html> <?php
$titel = "Impressum";
require "teile/kopf.php";
?>
<h1>Impressum</h1>
<p>Hofladen GmbH, Dorfstrasse 1.</p>
<?php require "teile/fuss.php"; ?> <?php
$titel = "Kontakt";
require "teile/kopf.php";
?>
<h1>Kontakt</h1>
<p>Telefon 0123 456789.</p>
<?php require "teile/fuss.php"; ?> <?php
$titel = "Startseite";
require "teile/kopf.php";
?>
<h1>Startseite</h1>
<p>Frisches aus dem Hofladen. Die Huelle um diesen Absatz steht jetzt nur noch an einer Stelle.</p>
<?php require "teile/fuss.php"; ?> include "datei.php" tut genau das, was man erwartet: PHP nimmt den Inhalt der genannten Datei und
führt ihn an dieser Stelle aus, so als stünde er dort. Gibt die Datei etwas aus, landet es in deiner
Antwort. Definiert sie eine Funktion, kannst du sie danach aufrufen.
Dasselbe tut require, und die Beispiele hier nehmen schon diese Form, weil sie für Kopf und Fuß
die richtige ist. Worin sich die beiden unterscheiden, steht am Ende dieser Lektion.
Damit liegt die Hülle nur noch einmal herum. teile/kopf.php enthält alles bis zur
Navigationsleiste, teile/fuss.php alles ab dem Fußbereich, und die eigentlichen Seiten enthalten
nur noch das, was sie voneinander unterscheidet. Der Menüpunkt kommt jetzt an einer Stelle dazu, und
alle Seiten haben ihn.
Beachte den Aufbau der drei Seiten: erst ein PHP-Block, dann die eingebundene Hülle, dann der Inhalt als ganz normales Markup, und am Ende der Fuß. Genau diesen Dreiklang benutzt der Kurs von hier an bis Abschnitt 16.
Die Dateien liegen dabei in einem Unterordner teile/. Das ist keine Vorschrift, sondern
Aufräumen. In Abschnitt 16 bekommt der Ordner einen echten Zweck, wenn es darum geht, was öffentlich
erreichbar sein soll und was nicht.
Die eingebundene Datei sieht deine Variablen
Das ist der bequemste und zugleich heikelste Teil. Eine mit include geholte Datei landet im
selben Gültigkeitsbereich wie die Zeile, die sie einbindet. Sie sieht also alle Variablen, die
dort schon gesetzt sind, und was sie selbst setzt, steht danach auch draußen zur Verfügung.
Im Beispiel nutzt kopf.php das aus: Es schreibt $titel in den Seitentitel, und gefüllt wird die
Variable von der Seite, die einbindet. Deshalb steht in jeder der drei Dateien eine Zeile
$titel = ... vor dem require.
Bequem ist das, weil man nichts übergeben muss. Heikel ist es aus demselben Grund. Vergisst du die
Zeile, meldet PHP Undefined variable $titel, und zwar an der Stelle, an der der Titel stehen
sollte: Im Reiter Browser steht dann die Warnung als Seitentitel. Und andersherum:
Setzt eine eingebundene Datei still eine Variable, die du weiter unten auch benutzt, überschreibt sie
dir deinen Wert, ohne dass irgendwo steht, dass sie das tut. Solche Fehler sucht man lange, weil die
Ursache in einer Datei liegt, die man beim Lesen gar nicht aufgeschlagen hat.
Die Faustregel dagegen ist einfach: Setz die Variablen, die eine Vorlage braucht, direkt über dem
include. Dann steht die Absprache dort, wo man sie sucht. Eine saubere Lösung mit einer richtigen
Übergabe kommt in Lektion 16.2.
require bricht ab, include macht weiter
<?php
// Die Datei teile/preisliste.php gibt es nicht. Absicht: Hier soll
// der Unterschied zwischen den beiden Schluesselwoertern zu sehen
// sein, und zwar im Terminal auf beiden Kanaelen.
echo "Vor dem include\n";
include "teile/preisliste.php";
echo "Nach dem include: das Programm laeuft weiter.\n";
require "teile/preisliste.php";
echo "Diese Zeile kommt nie an.\n"; Beide holen dieselbe Datei herein. Der Unterschied zeigt sich nur, wenn es sie nicht gibt. Dieses eine Beispiel läuft deshalb wieder als Skript im Terminal, wie in den Abschnitten davor: Auf einer Seite stünden beide Meldungen mitten im Text, und der Unterschied zwischen „weiter” und „Schluss” wäre schwerer zu sehen als auf zwei getrennten Kanälen.
include meldet zwei Warnungen auf dem Fehlerkanal und läuft weiter. Im Beispiel steht die
Zeile danach also noch in der Ausgabe. require meldet ebenfalls, bricht dann aber ab: Der Lauf
endet mit einem Fatal error, und die letzte Zeile kommt nie an. Den Exit-Code dazu holst du dir wie
in Lektion 1.4 mit php index.php; echo $? im Terminal, und da steht 255. Auf einem Server
sähest du davon nur die halbe Seite, denn ein Fatal error beendet die Anfrage und nicht den Server.
Daraus folgt die Regel, an die sich fast alle halten: require für alles, ohne das die Seite
keinen Sinn ergibt, also für Kopf, Fuß, Konfiguration und Klassen. include nur für Beiwerk, das
auch fehlen darf. Ein Kopfbereich, der fehlt, ergibt eine kaputte halbe Seite, und die ist schlimmer
als eine ehrliche Fehlermeldung.
Dazu kommen die beiden Varianten mit _once im Namen. require_once bindet dieselbe Datei nur beim
ersten Mal ein und tut danach nichts mehr. Für Kopf und Fuß brauchst du das nicht. Wichtig wird es,
sobald eine eingebundene Datei eine Funktion oder eine Klasse definiert: Die ein zweites Mal zu
definieren ist ein Fatal error, und der passiert schneller, als man denkt, wenn Datei A die Datei C
einbindet und Datei B ebenfalls.
Zum Mitnehmen
Kopf und Fuß einer Seite sehen auf jeder Seite gleich aus. Sie deshalb auf jeder Seite noch einmal hinzuschreiben, ist der Fehler, den man erst bemerkt, wenn ein Menüpunkt dazukommt und man acht Dateien ändern muss. PHP löst das mit einem Schlüsselwort.
Jetzt du
Basis Konto, kostenlosZu dieser Lektion gehört eine Aufgabe. Du schreibst den Code selbst, und nach jedem Lauf sagt dir eine Prüfliste, was schon stimmt.
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.
-
Aufgabe, dein Code läuft auf einem Server
Öffnet sich mit dem Basis Konto.