PHP中heredoc和nowdoc的优缺点

62
作为一个新手,我被建议尽量使用heredoc而不是太多的嵌套代码(请参见 Unexpected T_ELSE in php code)。但是我无法理解heredoc和nowdoc之间是否有重大区别。对于一个新手理解的重要性(即不是非常小的优势,而是对我来说重要的内容),heredoc和nowdoc相比另一个有哪些优点?
4个回答

143

现在文档 (Nowdocs) 对于单引号字符串的作用相当于 HereDoc 对于双引号字符串的作用。 Nowdoc 的形式和 Heredoc 类似,但是 Nowdoc 内部没有任何解析。这种构造方式非常适合嵌入 PHP 代码或其他大型文本块而无需转义。

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

换句话说:

$foo = 'bar';

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

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

$here"我在这里,酒吧!",而 $now"我现在在$foo!"

如果您不需要变量插值,但需要字符串中的特殊字符(如 $),那么Nowdocs更容易使用。就是这样。


如果我只有HTML标记(例如:<a hrefW> <strong>)要放在消息中(例如:I'm now, $foo!),从代码的速度/效率方面来看,使用nowdoc更好吗? 如果我必须包含一个变量,并希望它被解释,那么我应该使用heredoc? - Mathieu
1
从速度上来说,这不会有太大的影响。使用更加合理的方法。 - deceze

2
heredocs
1. heredocs文本的行为就像双引号字符串,没有双引号。
2. 在heredoc中的引号不需要转义,但是转义代码\n 换行符,\r 回车符,\t 水平制表符,\v 垂直制表符,\e 转义符,\f 换页符,\ 反斜杠,\$ 美元符号,\" 双引号仍然可以使用。变量会被扩展,但是在heredoc内部表达复杂变量时必须注意与字符串相同的细节。

示例:

$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文本的行为就像单引号字符串,但不需要单引号。
2. nowdocs中的引号不需要转义。变量不会在其中扩展。使用nowdocs的优点是可以嵌入PHP代码和转义码而无需转义。

示例:

$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 , \" ,\'
语法:现在文档(nowdoc)与限定符相同,使用 <<< 序列来标识,但后面的标识符要用单引号括起来,例如 <<<'NOWDOC'。所有限定符标识符的规则也适用于现在文档标识符,特别是关于结束标识符外观方面的规则。

0

当你不想处理引用和取消引用复杂字符串时,Nowdoc 是一个很好的选择,因为它不会解释任何引号并且不接受变量。由于这个原因,它非常适合手动显示实际代码片段!

然而,如果你在使用混合的heredocs和nowdocs来处理字符串内容块时,这是一种容易陷入的诱惑,你可能会在任何地方使用heredoc时遇到XSS(跨站脚本攻击)问题!因此,我不能推荐这种方法给刚开始学习php的开发者!相反,你应该尝试使用模板(无论是什么类型或什么模板引擎),来处理这些大块的信息。毕竟,你不希望在php中混有html,你-绝对不希望在其中包含用户注入javascript,例如:

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

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

因此,不要在适当的模板方法或模板引擎的位置使用HEREDOCS和NOWDOCS。

无论何时涉及到语言或技术之间的接口,都必须进行编码。PHP到SQL?绑定。PHP到HTML?编码。HTTP到PHP?


14
糟糕的建议。相反,应该学习什么是跨站脚本漏洞以及如何对输入进行净化。这些是服务器端编程的基本概念,对于初学者来说并不太复杂。使用模板系统来避免学习如何保护应用程序会使开发人员依赖于可能具有自己漏洞的辅助工具。更不用说,对于初学者要处理的项目,一个完整的模板系统通常是过度的。 - siliconrockstar
2
你认为初学者能够学习所有与XSS以及输入的净化和转义有关的问题,但是认为模板系统过于复杂。我认为你对哪种选项会带来最好的结果犯了错误,平均而言。这并不是说教育关于xss和转义不好,但这是一个复杂的话题,应该从默认情况下良好的转义标准开始,通常只有在使用模板引擎时才能得到,新手不应该自己编写模板引擎。 - Kzqai
跨站脚本攻击(XSS)或“为什么需要转义输出”假设你有一个网络论坛。如果攻击者创建了这样一篇帖子:“我喜欢论坛。<script type="text/javascript">window.location.href="http://malicioussite.com/malware-download-page";</script>”当其他用户查看该论坛帖子时,该JavaScript代码将会把他们发送到攻击网站!因此,需要转义输出 - 可以在呈现输出之前使用strip_tags(),或使用htmlspecialchars()或htmlentities()将HTML字符(如'<'和'>')转换为HTML实体(如'<'和'>')。模板引擎是为设计师准备的。 - siliconrockstar
1
我不同意@siliconrockstar的观点。这个答案并不是要建议人们不学习xss;事实上,阅读代码片段会让有洞察力的人想知道那里发生了什么。给初学者一个提示,在他们理解自己在做什么之前不要做什么是完全可以的。 - Félix Adriyel Gagnon-Grenier
1
唯一的“糟糕建议”就是建议一个连转义和单引号与双引号字符串都不理解的 PHP 初学者使用模板引擎来避免 XSS。你中间跳过了一些步骤。 - siliconrockstar
显示剩余6条评论

-1

Heredoc比"text"、echo 'text'和nowdoc快1000倍。

Sql1使用echo = 0.00011205673217773

Sql2使用heredoc = 9.7751617431641E-6

结果 = Sql1慢了1046.3414634146%。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接