Heredoc -Syntax und dessen richtige Anwendung
Sie befinden sich:
Home >
Php >
Heredoc -Syntax und dessen richtige Anwendung
Sobald ein PHP-String Variablen, Sonderzeichen und doppelte Anführungszeichen zugleich enthalten soll, wird der Code schnell unübersichtlich: Jedes Anführungszeichen braucht einen Backslash, jeder Umbruch eine eigene Verkettung. Genau dafür gibt es die Heredoc Syntax. Sie erlaubt mehrzeilige Texte ohne Escape-Zeichen, in denen Variablen trotzdem ausgewertet werden.
Diese Vereinfachung erlaubt es, einem String einen kompletten Text so an eine Variable zu
übergeben, dass die sonst übliche Verwendung von Escapezeichen als syntaktische
Elemente entfallen können.
Die Anwendung birgt allerdings ein paar Fehlerquellen, die unbedingt beachtet werden müssen.
Das nachfolgende Beispiel zeigt die Anwendung und die damit verbundenen Vereinfachungen.
<?php
$variable_eins = '<b>Inhalt der Variable</b>';
$mein_text = <<< EOT
Das hier ist ein kleiner PHP Text.
Es steht dem Anwender vollkommen frei "doppelte
Anführungszeichen" oder 'einfache'
zu setzen,
Auch $variable_eins wird innerhalb
dieses Textes korrekt mit dem entsprechenden
Inhalt angezeigt, auch hier sind keine Anführungszeichen
nötig. Selbst EOT kann geschrieben werden, solange
es nicht alleine als erster Ausdruck in einer
Zeile steht, wie das folgende
EOT;
echo $mein_text;
?>
Der Ausdruck EOT (End Of Text) ist in diesem Beispiel willkürlich gewählt, es kann
jeder beliebige Ausdruck verwendet werden, vorausgesetzen er ist in der Einleitung mit
„<<<“ definiert worden, und ist kein in PHP selbst definierter
Funktionsname wie array() oder Ähnliches.
Näheres regeln hier die allgemeinen Richtlinien für die Namensgebung unter PHP.
Der eindeutige Bezeichner im Heredoc Syntax ist ein Wort oder eine Zeichenkette, die an das
Schluss-Tag-Zeichen gebunden ist. Der Bezeichner muss eindeutig sein, damit der Compiler weiß,
wo der Heredoc Syntax endet.
Eine Konvention besteht darin, dass der beendende Ausdruck allein in einer neuen Zeile
stehen, und von einem Semikolon abgeschlossen sein muss, sowie dass er nicht mit einem
Leerzeichen beginnen darf. Das abschließende Zeichen darf jedoch innerhalb des Textes
angewendet werden, wie auch im oben angeführten Beispiel zu sehen ist. Zeilenumbrüche
werden ebenfalls so abgebildet oder geparst, wie sie im Heredoc – Block eingegeben
wurden.
Quelltext vom Beispiel

Heredoc – Syntax findet relativ selten Anwendung bei professionell programmierten
Scripten, obwohl es die Lesbarkeit gerade von gemischten Strings (Variablen und
allgemeiner Text) erheblich steigert. Ebenfalls wird die Eingabe des Textes wesentlich
vereinfacht. Dieser Umstand kommt gerade unerfahrenen Programmierern oftmals zugute. Heredoc
– Code ist erstmals ab PHP-Version 4.0 verfügbar.
Wichtiger Hinweis: Innerhalb eines Heredoc-Blocks können
keine PHP-Kommentare (// oder /* */) verwendet werden. Alles innerhalb des
Heredoc-Blocks wird als String-Inhalt behandelt und ausgegeben.
<?php
$string = <<<EOT
Dies ist ein Heredoc-String.
// Diese Zeile ist KEIN Kommentar!
Sie wird als normaler Text ausgegeben.
EOT;
echo $string;
?>
Das obige Beispiel würde Folgendes ausgeben:
Dies ist ein Heredoc-String.
// Diese Zeile ist KEIN Kommentar!
Sie wird als normaler Text ausgegeben.
Was ist der Unterschied zwischen dem Heredoc Syntax und dem Nowdoc Syntax in
PHP?
Der Hauptunterschied zwischen dem Heredoc Syntax und dem Nowdoc Syntax besteht darin, dass
der Heredoc Syntax Variablen interpretiert und expandiert, während der Nowdoc Syntax
die Variable als Literal behandelt. Bei Nowdoc wird der Bezeichner in einfache
Anführungszeichen gesetzen (z. B. <<<'EOT').
Nowdoc Syntax ist ein Weg, um in PHP einen String zu schreiben, der mehrere Zeilen umfasst,
ohne dass Variablen oder andere Daten interpretiert werden. Es ähnelt dem
Heredoc-Syntax, aber die Anführungszeichen sind einfache Anführungszeichen (')
statt doppelt (") und es gibt keine Interpretation.
Hier ist ein Beispiel für Nowdoc Syntax:
<?php
$nowdocString = <<<'EOT'
Dies ist mein Nowdoc-String.
Es kann über mehrere Zeilen gehen.
Variablen werden nicht interpretiert: $variable
EOT;
?>
Erklärung:
Dieser Code definiert einen sogenannten Nowdoc-String. Es handelt sich dabei um einen
speziellen Typ von String Literal, der in PHP verwendet wird. Der Nowdoc-String kann über
mehrere Zeilen gehen und Variablen werden nicht interpretiert. Dies bedeutet, dass Variablen
innerhalb des Strings nicht auf ihren Wert aufgelöst werden, sondern einfach als Text
ausgegeben werden.
Heredoc und Nowdoc: zwei Geschwister mit feinem Unterschied
Heredoc und Nowdoc sehen auf den ersten Blick fast gleich aus. Beide nutzen das gleiche Token-Format mit drei Kleiner-als-Zeichen, einem Bezeichner und einer Schlusszeile. Beide erlauben Zeilenumbrüche im String, ohne dass Sie sich mit verschachtelten Anführungszeichen herumschlagen müssen. Der entscheidende Unterschied steckt in einem einzigen Zeichen: den Anführungszeichen rund um den Bezeichner. Mit doppelten Anführungszeichen oder ganz ohne bekommen Sie Heredoc, das Variablen interpoliert. Mit einfachen Anführungszeichen erzeugst Sie Nowdoc, das den Inhalt eins zu eins ausgibt.
<?php
declare(strict_types=1);
$name = 'Mara';
/* Heredoc: $name wird durch den Wert ersetzt. */
$heredoc = <<<TEXT
Hallo $name, willkommen zurueck.
TEXT;
/* Nowdoc: $name bleibt als literaler Text stehen. */
$nowdoc = <<<'TEXT'
Hallo $name, willkommen zurueck.
TEXT;
echo $heredoc;
echo $nowdoc;
Sie können sich die Regel mit einer einfachen Eselsbrücke merken. Heredoc verhält sich wie ein doppelt gequoteter String, also mit Variablen-Ersetzung und Escape-Sequenzen. Nowdoc verhält sich wie ein einfach gequoteter String, also strikt literal. Diese Unterscheidung ist nicht nur akademisch, sondern hat handfeste Konsequenzen für Sicherheit und Lesbarkeit. Sobald Sie Inhalte haben, in denen Dollarzeichen vorkommen sollen, ist Nowdoc fast immer die richtige Wahl.
Indented Heredoc seit PHP 7.3
Eines der nervigsten Details der alten Heredoc-Syntax war der Closing-Marker. Er müssene komplett am Zeilenanfang stehen, ohne ein einziges führendes Whitespace. Mitten in einer eingerückten Methode wurde Ihr Code dadurch zerrissen, weil die Schlusszeile zwingend an die linke Spalte müssene. Seit PHP 7.3 ist das vorbei. Sie dürfen den Closing-Marker einrücken, und PHP entfernt diese Einrückung automatisch von jeder Inhaltszeile.
<?php
declare(strict_types=1);
class Mailer
{
public function nachricht(string $name): string
{
/* Closing-Marker eingerueckt */
return <<<TEXT
Hallo $name,
schoen, dass du wieder da bist.
Bis gleich!
TEXT;
}
}
echo (new Mailer())->nachricht('Jonas');
Wichtig ist, dass die Einrückung der Schlusszeile als Mass dient. Jede Inhaltszeile muss mindestens so weit eingerückt sein wie der Closing-Marker, sonst wirft PHP einen Parse-Fehler. Tabs und Spaces dürfen Sie nicht mischen, sonst gibt es ebenfalls einen Fehler. Diese Regel klingt streng, schützt sich aber vor schwer auffindbaren Whitespace-Bugs.
Komplexe Variablen-Ausdrücke in Heredoc
Einfache Variablen wie $name können Sie direkt in den Heredoc schreiben. Sobald es aber um Array-Indizes mit Strings, Objekt-Properties oder gar Methodenaufrufe geht, wird die Sache anspruchsvoller. PHP bietet dafür die geschweifte Notation, mit der Sie nahezu jeden gültigen Ausdruck einbetten können. Die saubere Syntax dafür ist {$ausdruck}, alternativ auch das exotischere ${...}. Die erste Variante ist die empfohlene, weil sie sich genauso verhält wie in einem normalen doppelt gequoteten String.
<?php
declare(strict_types=1);
class Profil
{
public function __construct(
public readonly string $vorname,
public readonly array $kontakt,
) {}
public function anzeigeName(): string
{
return strtoupper($this->vorname);
}
}
$profil = new Profil('Lea', ['mail' => 'lea@example.com']);
$ausgabe = <<<TEXT
Vorname: {$profil->vorname}
Mail: {$profil->kontakt['mail']}
Anzeige: {$profil->anzeigeName()}
TEXT;
echo $ausgabe;
Eine Falle gibt es trotzdem: Funktionsaufrufe direkt im Heredoc sind nicht erlaubt, nur Methoden auf Objekten in geschweiften Klammern. Wenn Sie das Ergebnis einer normalen Funktion einbetten möchten, müssen Sie den Wert vorher in eine Variable schreiben. Für komplexere Formatierungen lohnt sich oft ein Blick auf sprintf.
HTML-Templates mit Heredoc bauen
Heredoc spielt seine Stärke voll aus, wenn Sie kleine HTML-Schnipsel direkt in PHP zusammenbauen wollen. Sie müssen keine Anführungszeichen escapen, und Zeilenumbrüche werden eins zu eins in den Output übernommen. Wichtig ist dabei nur, dass alle Werte aus User-Eingaben oder externen Quellen vorher durch htmlspecialchars laufen. Sonst handelst Sie sich Cross-Site-Scripting ein.
<?php
declare(strict_types=1);
function rendereKarte(array $artikel): string
{
/* Alle dynamischen Werte vorher escapen. */
$titel = htmlspecialchars($artikel['titel'], ENT_QUOTES, 'UTF-8');
$autor = htmlspecialchars($artikel['autor'], ENT_QUOTES, 'UTF-8');
$teaser = htmlspecialchars($artikel['teaser'], ENT_QUOTES, 'UTF-8');
$url = htmlspecialchars($artikel['url'], ENT_QUOTES, 'UTF-8');
return <<<HTML
<article class="card">
<h3><a href="$url">$titel</a></h3>
<p class="meta">von $autor</p>
<p>$teaser</p>
</article>
HTML;
}
echo rendereKarte([
'titel' => 'Heredoc verstehen',
'autor' => 'Tom',
'teaser' => 'Multi-line Strings sauber in PHP nutzen.',
'url' => '/heredoc.html',
]);
Achten Sie darauf, dass Sie die geschweiften Klammern nutzen, sobald Sie Array-Zugriffe oder Properties einbettest. Bei einfachen Variablen können Sie sie weglassen. Wenn Ihre Templates größer werden, sollten Sie sie irgendwann in echte Template-Dateien auslagern. Heredoc ist ideal für überschaubare Bausteine, für eine vollständige View-Schicht greift man besser zu Twig, Blade oder einfachen include-Dateien.
Heredoc oder sprintf: wann was?
Sowohl Heredoc als auch sprintf erzeugen formatierte Strings. Sie lösen aber unterschiedliche Probleme. Heredoc ist stark, wenn Sie längere mehrzeilige Blöcke haben und wenig Werte einsetzen. sprintf punktet bei vielen Werten, bei Zahlenformatierung und bei Übersetzbarkeit, weil der Format-String unabhängig von den Daten ist.
| Situation | Empfehlung |
|---|
| Mehrzeilige HTML- oder Mail-Templates | Heredoc | Zahlen formatieren (%05d, %.2f) | sprintf | | Mehrsprachige Texte mit Argumenten | sprintf (oder vsprintf) | | SQL-Templates ohne Interpolation | Nowdoc | | Kurze einzeilige Strings | Doppelte Quotes | | Code-Generatoren mit vielen Dollarzeichen | Nowdoc |
<?php
declare(strict_types=1);
$name = 'Mira';
$preis = 1234.5;
/* Heredoc fuer das mehrzeilige Layout. */
$kopf = <<<TEXT
Rechnung fuer: $name
TEXT;
/* sprintf fuer die exakte Zahlenformatierung. */
$zeile = sprintf('Betrag: %s €', number_format($preis, 2, ',', '.'));
echo $kopf . "
" . $zeile;
Beide Werkzeuge schliessen sich nicht aus. In größeren Templates kombinieren Sie sie sogar gerne: das Gerüst baut Heredoc, einzelne Zellen mit Zahlen oder Datumsangaben formatierst Sie vorher per sprintf und legen das Ergebnis in eine Variable, die Sie dann ins Heredoc einsetzen. So bleibt jeder Teil bei dem, was er am besten kann.
Mehrzeilige SQL-Queries als Nowdoc
SQL-Queries sind ein typischer Fall, in dem Sie keine Interpolation wollen. Erstens kommen Dollarzeichen in SQL gelegentlich tatsächlich vor, etwa in MySQL-Variablen oder PostgreSQL-Identifiern. Zweitens, viel wichtiger: Werte gehören niemals direkt in den Query-String, sondern als Parameter über Prepared Statements via PDO. Mit Nowdoc machen Sie diesen Vorsatz auch syntaktisch sichtbar.
<?php
declare(strict_types=1);
$pdo = new PDO('mysql:host=localhost;dbname=app;charset=utf8mb4', 'user', 'pass', [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);
/* Nowdoc: keinerlei Interpolation, ideal fuer SQL. */
$sql = <<<'SQL'
SELECT u.id, u.email, p.titel
FROM user u
JOIN posting p ON p.user_id = u.id
WHERE u.aktiv = 1
AND p.erstellt_am >= :seit
ORDER BY p.erstellt_am DESC
LIMIT :max
SQL;
$stmt = $pdo->prepare($sql);
$stmt->bindValue(':seit', '2026-01-01');
$stmt->bindValue(':max', 50, PDO::PARAM_INT);
$stmt->execute();
Der große Vorteil ist die Kopier-Sicherheit. Sie können die Query so wie sie da steht in einen MySQL-Workbench- oder DBeaver-Editor kopieren und gegen Ihre Datenbank laufen lassen. Mit Heredoc wären Dollarzeichen ein Problem, mit Nowdoc nicht. Auch die Indented-Schreibweise seit PHP 7.3 funktioniert mit Nowdoc, sodass die Query schön in Ihren Methoden-Block einrückt, ohne den Lesefluss zu zerreissen.
Heredoc oder Nowdoc: kleine Entscheidungshilfe
Wenn Sie sich trotzdem unsicher sind, hilft ein Mini-Diagramm. Es bringt die wichtigsten Fragen auf eine einzige Achse: Brauchst Sie Variablen-Interpolation oder nicht? Alles andere ergibt sich daraus.
flowchart TD
A[Mehrzeiliger String?] --> B{Variablen einsetzen?}
B -->|Ja| C[Heredoc HEREDOC]
B -->|Nein| D[Nowdoc NOWDOC]
Diese eine Frage erspart sich 95 Prozent aller Diskussionen im Code-Review. Variablen einsetzen heißt Heredoc. Literal heißt Nowdoc. Den Rest erledigen die Indented-Marker seit PHP 7.3 und ein bisschen Disziplin beim Escapen von Werten. Wenn Sie in einem großen Block plötzlich gemischte Anforderungen haben, also einen Teil interpoliert und einen Teil literal, dann teile den Block einfach in zwei Heredoc- und Nowdoc-Blöcke und konkatenierst sie mit dem Punkt-Operator.
Praxisbeispiel: E-Mail-Template mit Heredoc
Zum Abschluss bauen wir ein realistisches Mini-Template. Eine Bestellbestätigung, die per E-Mail rausgeht. Sie hat eine Anrede mit Vornamen, eine Tabelle mit Positionen und einen Footer. Genau die Art von Text, die Sie in jedem Online-Shop und in vielen Backend-Tools immer wieder schreiben. Mit Heredoc, sauber escapten Werten und einer kleinen Helfer-Funktion bleibt das übersichtlich.
<?php
declare(strict_types=1);
final class Bestellung
{
public function __construct(
public readonly string $vorname,
public readonly string $bestellnummer,
public readonly array $positionen,
) {}
public function summe(): float
{
$s = 0.0;
foreach ($this->positionen as $p) {
$s += $p['menge'] * $p['preis'];
}
return $s;
}
}
function rendereBestaetigung(Bestellung $b): string
{
$name = htmlspecialchars($b->vorname, ENT_QUOTES, 'UTF-8');
$nr = htmlspecialchars($b->bestellnummer, ENT_QUOTES, 'UTF-8');
$zeilen = '';
foreach ($b->positionen as $pos) {
$titel = htmlspecialchars($pos['titel'], ENT_QUOTES, 'UTF-8');
$zeilen .= sprintf(
" %2d x %-30s %8s €
",
$pos['menge'],
$titel,
number_format($pos['preis'], 2, ',', '.')
);
}
$summe = number_format($b->summe(), 2, ',', '.');
return <<<MAIL
Hallo $name,
vielen Dank fuer deine Bestellung mit der Nummer $nr.
Hier deine Positionen im Ueberblick:
$zeilen
Gesamtbetrag: $summe €
Liebe Gruesse
Dein Shop-Team
MAIL;
}
Beachte, wie wir die Verantwortlichkeiten trennen. sprintf kümmert sich um die exakte Spaltenausrichtung mit fester Breite. number_format bringt die Zahlen ins deutsche Format. htmlspecialchars sorgt dafür, dass Sonderzeichen aus User-Eingaben nicht zu Layout-Problemen oder Sicherheitslücken führen. Heredoc liefert das Gerüst und sorgt dafür, dass das Template als Ganzes lesbar bleibt. Genau dieses Zusammenspiel ist es, was Heredoc und Nowdoc in Ihrem Werkzeugkasten so wertvoll macht. Häufige Fragen zur Heredoc SyntaxVier Punkte tauchen beim Einstieg immer wieder auf. 1Wann lohnt sich die Heredoc Syntax gegenüber normalen Strings?Ab etwa drei Zeilen Text mit eingebetteten Variablen. Darunter ist ein einfacher String meist lesbarer. Sobald doppelte Anführungszeichen im Text vorkommen, spart Heredoc sofort das Escapen. 2Was ist der Unterschied zwischen Heredoc und Nowdoc?Heredoc wertet Variablen aus, Nowdoc nicht. Die Kennung entscheidet: <<<TEXT interpoliert, <<<'TEXT' mit einfachen Anführungszeichen gibt den Inhalt buchstabengetreu aus. 3Warum bekomme ich einen Parse-Error am Ende des Blocks?Meist steht hinter der schließenden Kennung noch ein Zeichen oder davor ein Leerzeichen zu viel. Seit PHP 7.3 darf die Kennung eingerückt sein, aber der Inhalt muss dann mindestens genauso weit eingerückt sein. 4Darf ich HTML aus Nutzereingaben in Heredoc schreiben?Nur durch htmlspecialchars() gefiltert. Heredoc ersetzt Variablen wie ein doppelt gequoteter String, ohne zu prüfen. Ungefiltert landet Fremdcode direkt in Ihrer Seite. Jetzt die anderen Wege der Textausgabe ansehen oder die Details im PHP-Handbuch nachlesen.
weiter zum nächsten Kapitel:
Grundlagen und Methoden zum Einbinden von Dateien in PHP über include
|