Skip to content
Theory · Strings · lesson 2 of 9

heredoc and nowdoc

In the previous lesson the whole text of a string fit on one line of code. But a form can run to several pages: a letter to a user, a piece of an HTML page, a database query.

Writing such text in quotes is awkward. Every line needs a \n at the end, and every quote inside has to be escaped, with a backslash in front of it, as in \". PHP has a separate notation for long text:

PHP
<?php

$name = 'Anna';
$count = 3;
$letter = <<<TEXT
Hello, $name!
You have $count new messages.
TEXT;
echo $letter, "\n";
// Hello, Anna!
// You have 3 new messages.

Let's take the block apart:

  1. <<<TEXT opens it: three "less than" signs and a marker word. You choose the marker yourself, usually in capitals: TEXT, HTML, SQL.
  2. The lines below are the text itself. The line breaks in it are real, so you do not write \n.
  3. TEXT; on a line of its own closes the block. The marker is the same as after <<<, and the semicolon ends the statement.
  4. The line break before the closing marker is not part of the text, which is why the echo adds "\n".

The marker is also called the block's identifier.

heredoc: a form over several lines

This block is called a heredoc. Inside, it works like double quotes:

  • it substitutes variables, including ones in curly braces {$name};
  • it processes \n, \t and the other escape sequences;
  • it treats quotes as ordinary characters: He said "hi" is written as is, without \".

That makes a heredoc handy for a letter or HTML with values from variables.

nowdoc: a photocopy over several pages

If you put the marker in single quotes, you get a nowdoc. It works like single quotes: it substitutes nothing and prints the text letter for letter.

PHP
$raw = <<<'TEXT'
Hello, $name!\n
TEXT;
echo $raw, "\n"; // Hello, $name!\n

Only the opening marker takes the quotes; the block is still closed by TEXT;. A nowdoc is the choice for text where a $ sign must stay a sign: code samples, templates, database queries.

Interviewers ask how a heredoc differs from a nowdoc. The answer fits in one sentence: a heredoc behaves like double quotes, and a nowdoc like single quotes.

Indenting the closing marker

A block often sits inside indented code. You can move the closing marker to the right along with the code, and PHP then removes as many spaces from the start of every line of the text:

PHP
$html = <<<HTML
    <p>
      Hi, {$name}!
    </p>
    HTML;
echo $html, "\n";
// <p>
//   Hi, Anna!
// </p>

Let's go step by step:

  1. There are four spaces before the marker HTML;.
  2. PHP removes four spaces from the start of every line of the text.
  3. The line Hi, {$name}! had six spaces, so two remain.

This is where the form stops being an exact picture. The indentation before the closing marker is a rule of the block, not part of the text, and PHP cuts it from every line. Every PHP version since 7.3 works this way.

Common mistake

The text was written from the left edge, while the closing marker was aligned with the code:

PHP
$text = <<<TEXT
Hello, $name!
    TEXT; // ✗
echo $text, "\n";
TEXT
Parse error: Invalid body indentation level (expecting an indentation level of at least 4)

PHP has to remove four spaces from a line that does not have them, and it reports that it expected an indentation of at least four spaces. This is a parse error, so not a single line of the program runs. The fix is to indent the text at least as far as the marker, or to remove the marker's indentation.

Key points

  • A heredoc <<<TEXT … TEXT; is a multi-line string that works like double quotes.
  • A nowdoc <<<'TEXT' works like single quotes and substitutes nothing.
  • The line break before the closing marker is not part of the string.
  • PHP removes the closing marker's indentation from every line, and a line indented less is a parse error.