62

As a newbie, I have been advised to preferably use heredoc compared to too many nested codes (see Unexpected T_ELSE in php code).

But I can't manage to understand if there is a significant difference between heredoc and nowdoc.

What would be the advantages for heredoc and nowdoc compared to the other one that would be important for a newbie to understand (i.e. not very minor advantages but important to understand for me).

ADyson
  • 57,178
  • 14
  • 51
  • 63
Mathieu
  • 4,587
  • 11
  • 57
  • 112

4 Answers4

143

Nowdocs are to single-quoted strings what heredocs are to double-quoted strings. A nowdoc is specified similarly to a heredoc, but no parsing is done inside a nowdoc. The construct is ideal for embedding PHP code or other large blocks of text without the need for escaping.

http://php.net/manual/en/language.types.string.php#language.types.string.syntax.nowdoc

In other words:

$foo = 'bar';

$here = <<<HERE
    I'm here, $foo !
HERE;

$now = <<<'NOW'
    I'm now, $foo !      
NOW;

$here is "I'm here, bar !", while $now is "I'm now, $foo !".

If you don't need variable interpolation but need special characters like $ inside your string, Nowdocs are easier to use. That's all.

Chemaclass
  • 1,933
  • 19
  • 24
deceze
  • 510,633
  • 85
  • 743
  • 889
2

heredocs
1. heredocs text behaves just like a double-quoted string, without the double quotes.
2. Quotes in a heredoc do not need to be escaped, but the escape codes \n linefeed,
\r carriage return, \t horizontal tab, \v vertical tab, \e escape, \f form feed, \ backslash,\$ dollar sign,\" double-quote
can still be used. Variables are expanded, but the same care must be taken when expressing complex variables inside a heredoc as with strings.

Example :

$myname='Tikku';
$heredoc_exmaple= <<<HEREDOC
\\n ,\\r ,\t ,\r ,\\v ,\\e ,\f ,\\ , \ ,$89 ,$ , $myname , ' , \$myname ,  \" ,\'
HEREDOC;
echo $heredoc_exmaple;

//OUTPUT \n ,\r ,   , ,\v ,\e , ,\ , \ ,$89 ,$ , Tikku , ' , $myname , \" ,\'

nowdocs
1. nowdocs text behaves just like a single-quoted string, without the single quotes.
2. Quotes in a nowdocs do not need to be escaped.Variables are not expanded in it.Advantage of nowdocs is embedding PHP code and escape codes without the need for escaping.

Example :

$myname='Tikku';
$nowdoc_exmaple= <<<'NOWDOC'
\\n ,\\r ,\t ,\r ,\\v ,\\e ,\f ,\\ , \ ,$89 ,$ , $myname  , ' , \$myname ,  \" ,\'
NOWDOC;

echo $nowdoc_exmaple;

//OUTPUT \\n ,\\r ,\t ,\r ,\\v ,\\e ,\f ,\\ , \ ,$89 ,$ , $myname , ' , \$myname , \" ,\'

Syntax: A nowdoc is identified with the same <<< sequence used for heredocs, but the identifier which follows is enclosed in single quotes, e.g. <<<'NOWDOC'. All the rules for heredoc identifiers also apply to nowdoc identifiers, especially those regarding the appearance of the closing identifier.

Dhairya Lakhera
  • 4,445
  • 3
  • 35
  • 62
0

Nowdoc is great when you don't want to deal with quoting and unquoting complex strings, since it won't interpret any quotes and it won't accept variables. As such, it's well suited to manually displaying actual code snippets!

However, if you're using a mix of heredocs and nowdocs for blocks of string content, which is an easy temptation to fall into, you could easily run into XSS (cross site scripting) problems where-ever you use heredoc! As such, this approach is just not clean enough for me to recommend to a developer starting out in php! Instead, you should be trying to use templates (of whatever kind, or whatever template engine you like), for these large blocks of information. After all, you don't want html in your php, and you -certainly- don't want user-injected javascript, like:

$username = '<script>alert(document.cookie.toString())</script>';

$insecure_example = <<<HERE
    I really like having my site exploited, $username
HERE;

So don't use HEREDOCS and NOWDOCS in the place of a proper templating approach or a templating engine.

Where-ever there is an interface between languages or technologies, you have to encode. php to sql? bind. php to html? encode. http to php?

Kzqai
  • 22,588
  • 25
  • 105
  • 137
  • 14
    Horrible advice. Instead, learn what a cross site scripting vulnerability is, and how to sanitize input. These are fundamental concepts in server-side programming that are not too complex for a beginner to grasp. Using a template system to avoid having to learn how to secure your application makes the developer dependent on a crutch that may or may not have its own vulnerabilities. Not to mention, a full-blown templating system is usually overkill for the kinds of projects a beginner is going to take on. – siliconrockstar Dec 30 '13 at 15:54
  • 2
    You think a beginner is going to be able learn -all- the issues with XSS and sanitizing & escaping input, but consider a templating system overkill. I think you're mistaken on which option is going to lead to the best results, on average. That's not to say that education about xss and escaping isn't good, but it's a complex topic that should start with a good standard of escaping by default, which is generally only something that you get with a templating engine, and newcomers shouldn't roll their own templating engine. – Kzqai Dec 30 '13 at 20:41
  • Cross Site Scripting (XSS) or 'Why to Escape Output' Say you have a web forum. What if an attacker creates a post like this: 'I love forums.' When that forum post is shown to other users, that javascript is going to send them to an attack site! So escape output - you can use strip_tags() before rendering the output, or use htmlspecialchars() or htmlentities() to convert html characters like '<' and '>' into HTML entities like '<' and '>'. Template engines are for designers. – siliconrockstar Jan 04 '14 at 04:06
  • As a developer you should never allow such an easy mistake to get through. Don't use heredoc or nowdoc for generating public views. These methods are incredibly useful as long as you don't do dumb things with them. Currently I'm using nowdoc to generate cakephp templates, which doesn't parse any user input. – Michael Ozeryansky Jul 31 '14 at 23:05
  • 1
    I disagree with @siliconrockstar. This answer is not about advising people to not learn about xss; as a matter of fact, reading the code snippet would make an observative mind wonder what is happening there. Giving beginning programmers a hint on what not to do until they understand what they are doing is **perfectly** fine. – Félix Adriyel Gagnon-Grenier Jul 07 '16 at 18:57
  • @FélixGagnon-Grenier - I did not advise against learning about XSS, I recommended it. Even beginners should have a basic understanding of XSS, CSRF, and SQL injection. – siliconrockstar Jul 09 '16 at 00:01
  • @siliconrockstar I know. "**This answer** is not about advising people to not learn about xss" doesn't mean I think you are doing so. It means I disagree with your assertion that this is terrible advice, for reasons mentioned. – Félix Adriyel Gagnon-Grenier Jul 09 '16 at 00:06
  • 1
    The only 'terrible advice' was suggesting a PHP beginner, who doesn't even understand escaping and single vs double-quoted strings, to use a templating engine in order to avoid XSS. You're skipping some steps in there. – siliconrockstar Jul 09 '16 at 02:04
  • A good way to mentally protect against XSS or other kinds of injection is to name your variables like $username_unsafe and $username_safe, and then learn which sanitization function gets you from one value to the other. – donquixote Apr 07 '20 at 19:47
  • In general, if you think heredoc is not safe, the same does apply to basic string concatenation, and to variables inserted into double-quoted strings. – donquixote Apr 07 '20 at 19:48
  • The alternative doesn't need to be a template engine. What also works is a string replacement function with sanitisation built in, like format_string() in Drupal. You could use this in combination with nowdoc. Or if it is for a database query, a typical query builder would have a string replace mechanism with built-in sanitization suited for SQL. – donquixote Apr 07 '20 at 19:52
-1

Heredoc is 1000 times faster than "text", echo 'text' and nowdoc.

Sql1 with echo = 0.00011205673217773

sql2 with heredoc = 9.7751617431641E-6

Result = Sql1 Is 1046.3414634146% slow.