What are PHP Heredoc & Nowdoc?
With the arrival of PHP 7.3 last month came some interesting changes to the existing heredoc and nowdoc syntaxes. However, not everyone I spoke to even knew that this syntax existed in PHP, so now seems like a good opportunity to take a look at what they are and how to use them.
In PHP we have several options for specifying a string value. The two most common approaches are to use either single or double quotes. We also have heredoc and nowdoc syntaxes which are useful when we want to define a multiline string.
Before we look at heredoc and nowdoc let’s refresh our memories on single and double quote strings. There are a couple of differences between these two methods.
When we use a double quote string we can use escaped characters like
\n which gets interpreted as a new line break and variables will get substitued for their respective values. For example:-
$foo = 'bar'; echo "Hello $foo\nGoodbye!"; // Output:- // Hello bar // Goodbye!
Single quoted strings are literal.
- This means escaped characters do not expand, e.g.
'\n'will not result in a new line, the string will literally be a backslash followed by the character n
- Variables do not get replaced by their respective values
$foo = 'bar'; echo 'Hello $foo\nGoodbye!'; // Output:- // Hello $foo\nGoodbye!
The one exception is you can use
\' in a single quoted string if you need to include a single quote in the string value.
So what about the heredoc and nowdoc syntaxes? They provide an alternative way of defining strings in PHP. They are particularly useful when we need to define a string over multiple lines.
They work by defining an identifier that will mark the start and end of the string. The identifier can be any alphanumeric value following the same rules we’d use for variable names. One important thing to note with the identifier is that as of PHP 7.3 you need to make sure that it does not appear within the string itself.
Here’s an example of a heredoc.
echo <<<EOT Hello World. Goodbye! EOT; // Output:- // Hello World. // Goodbye!
The identifier for this heredoc is
EOT. Remember we could have used any alphanumeric identifier to mark the beginning and end of the string, e.g.
MARK. The opening identifier must always be proceeded by the
Heredoc’s are equivalent to a double quoted string. That means any variables in the string will get substitued for their respective values. We could rewrite the double quoted string example above as a heredoc:-
$foo = 'bar'; echo <<<EOT Hello $foo Goodbye! EOT; // Output:- // Hello bar // Goodbye!
Nowdoc’s are equivalent to a single quoted string. To denote a nowdoc we just need to use single quotes around the opening identifier:-
$foo = 'bar'; echo <<<'EOT' Hello $foo Goodbye! EOT; // Output:- // Hello $foo // Goodbye!
The placement of the closing identifier is important. Prior to PHP 7.3 it had to always be placed on a new line followed by a semi-colon and with no white-space in front of it. So all the examples above would be valid. However, as of PHP 7.3 these rules have been relaxed a little.
New Closing Identifier Rules
As of PHP 7.3 the following is valid.
If we use whitespace in front of the closing identifier then the same amount of whitespace will be deducted from the start of each line of the string.
// Valid from PHP 7.3 echo <<<EOT SELECT * FROM `contacts` WHERE `telephone` IS NOT NULL; EOT; // Output:- // SELECT * FROM `contacts` // WHERE `telephone` IS NOT NULL;
In this example, there are four spaces before the closing identifier
EOT. This means four spaces will be removed from the start of both lines of the string. As a result only the second line will look indented.
It’s important to make sure that none of the lines of the string have less whitespace in front of them than in front of the closing identifier; if this is the case a syntax error will be thrown by PHP.
// This is invalid code echo <<<EOT SELECT * FROM `contacts` WHERE `telephone` IS NOT NULL; EOT;
In the above example PHP throws a syntax error because the first line of the string has no whitespace in front of it, but the closing identifier requires four spaces.
Another change to the syntax that was introduced with PHP 7.3 is that the closing identifier can be followed by other code on the same line. So as of PHP 7.3 the following is valid:-
// Valid as of PHP 7.3 $strings = [ 'Looney Toons', <<<EOT Steven Spielberg Presents Tiny Toon Adventures EOT, 'Animaniacs', ];
Heredoc and nowdoc provide useful alternatives to defining strings in PHP to the more widely used quoted string syntax. They are especially useful when we need to define a string that spans multiple lines (new lines are also interpreted when used in quoted strings) and where use of whitespace is important. We also don’t need to worry about escaping quote marks when using heredoc and nowdoc.
Both can make strings more readable in code, particularly with the relaxation of both syntaxes introduced in PHP 7.3. So next time you need to work with a long string, perhaps you’ll consider using heredoc or nowdoc to get the job done.